Vue normale

Il y a de nouveaux articles disponibles, cliquez pour rafraîchir la page.
À partir d’avant-hierFlux principal

Pre-Filtering Multi-table Lookups

A very common requirement which is being request frequently is having a lookup table that points to multiple tables similar to the out of the box customer lookup type that can point out to either a contact or account.

This feature was released in July 2021 but I hadn’t the chance to try it till now and it came up with a challenge to using it which is Prefiltering this new type of lookup and I have searched and googled and everything and I really could not find someone who tried it, Many articles pointing out how to create this column typeand how it looks like but none really explained how to add prefiltration so it does not display all the records but show them as filtered based on a predefined criteria.

This article by Nick Doelman has a very good explanation to Polymorphic lookups.

This article describes how to do pre-filtration to a normal lookup type.

Also with the help of the XRMToolbox Polymorphic Lookup Creator it was very easy to create the polymorphic lookup which for the sake of the example below my lookup needed to point to either contact or user tables with a pre-search filter where first name = Mira

SO when it came to the prefiltration it was pretty easier than I thought and I just tried it and to my Surprise it worked, so all I did is used the normal way for lookup filtration but added a custom filter for each of my tables.

function FilterPolymporphicLookup(executionContext){
	formContext = executionContext.getFormContext();
formContext.getControl("new_polymorphiclookupid").addPreSearch(filterPolymorphic);
}
 function filterPolymorphic() {

    var contactFilter = "<filter type='and'><condition attribute='firstname' operator='eq' value='Mira' /></filter>";
    var userFilter = "<filter type='and'><condition attribute='firstname' operator='eq' value='Mira' /></filter>";

    formContext.getControl("new_polymorphiclookupid").addCustomFilter(contactFilter, "contact");
    
    formContext.getControl("new_polymorphiclookupid").addCustomFilter(userFilter, "systemuser");

}

Multilookup

miraghaly

Pre-Filtering Multi-table Lookups

A very common requirement which is being request frequently is having a lookup table that points to multiple tables similar to the out of the box customer lookup type that can point out to either a contact or account.

This feature was released in July 2021 but I hadn’t the chance to try it till now and it came up with a challenge to using it which is Prefiltering this new type of lookup and I have searched and googled and everything and I really could not find someone who tried it, Many articles pointing out how to create this column typeand how it looks like but none really explained how to add prefiltration so it does not display all the records but show them as filtered based on a predefined criteria.

This article by Nick Doelman has a very good explanation to Polymorphic lookups.

This article describes how to do pre-filtration to a normal lookup type.

Also with the help of the XRMToolbox Polymorphic Lookup Creator it was very easy to create the polymorphic lookup which for the sake of the example below my lookup needed to point to either contact or user tables with a pre-search filter where first name = Mira

SO when it came to the prefiltration it was pretty easier than I thought and I just tried it and to my Surprise it worked, so all I did is used the normal way for lookup filtration but added a custom filter for each of my tables.

function FilterPolymporphicLookup(executionContext){
	formContext = executionContext.getFormContext();
formContext.getControl("new_polymorphiclookupid").addPreSearch(filterPolymorphic);
}
 function filterPolymorphic() {

    var contactFilter = "<filter type='and'><condition attribute='firstname' operator='eq' value='Mira' /></filter>";
    var userFilter = "<filter type='and'><condition attribute='firstname' operator='eq' value='Mira' /></filter>";

    formContext.getControl("new_polymorphiclookupid").addCustomFilter(contactFilter, "contact");
    
    formContext.getControl("new_polymorphiclookupid").addCustomFilter(userFilter, "systemuser");

}

Upgrading the Microsoft 365 Groups and Teams Membership Report Script

Moving the Microsoft 365 Groups Report Script from Azure AD to the Graph SDK

Two years ago, I wrote a script to report the membership of Microsoft 365 groups and teams. The script processes user accounts to find accounts they are members of and generates detailed and summary reports.

As it turned out, I ended up writing two versions of the script: one using standard PowerShell cmdlets from the Exchange Online PowerShell and Azure AD modules, the other using Graph API requests. The Graph version is faster but some people don’t like Graph-based scripts because of the requirement to register an Azure AD app, consent to permissions, and so on.

Time and technology march on and it’s time to review any script that uses the Azure AD module because of its imminent deprecation in June 2023. Imminent sounds like a strange word to use about something that will happen in five and a half months but time slips away and there’s always something different to be done. I had the time and was already committed to upgrading the script to report “stale” guest accounts, so it seemed like a good idea to plunge into the code and replace the Azure AD and Exchange Online cmdlets with the Microsoft Graph PowerShell SDK.

Scripts to Process Azure AD Accounts and Groups

I’ve come to the view that it’s now best to use the SDK for anything to do with Azure AD accounts and groups. Because the Exchange Online management module contains cmdlets that operate against Microsoft 365 groups, I could have used those cmdlets in the script, but it’s easier when a script uses just the one module.

The two versions of the scripts are available from GitHub:

Changes to Upgrade to the SDK

Among the changes made to upgrade the script were:

  • Connect to the Graph with Connect-MgGraph, setting appropriate permissions and selecting the beta endpoint.
  • Replace the Exchange Get-Organization cmdlet with SDK Get-MgOrganization to fetch tenant name.
  • Replace Get-AzureADUser with Get-MgUser. The filter used with Get-MgUser fetches only licensed accounts (excludes guests and accounts used for room and resource mailboxes). Replacing Get-AzureADUser is one of the more common changes that people will make as they upgrade scripts. See this article for more information.
  • Replace Get-UnifiedGroup with Get-MgTeam to fetch a list of team-enabled groups.
  • Replace Get-Recipient with the Graph MemberOf API to find the set of groups a user is a member of. The Invoke-MgGraphRequest cmdlet runs the Graph query to remove the need to register an app.
  • Use Get-MgGroupOwner to return group owners instead of fetching this information from the ManagedBy property available with Get-UnifiedGroup.
  • Other miscellaneous changes of the type that you find you make when reviewing code.

The code generates the same reports as before (HTML report  – Figure 1 – and two CSV files). All the change is in the plumbing. Nothing is different above water.

HTML version of the Microsoft 365 Groups and Teams report

Microsoft 365 Groups Report
Figure 1: HTML version of the Microsoft 365 Groups and Teams report

Unpredictable Upgrade Effort

It’s hard to estimate how long it will take to upgrade a script to use the Microsoft Graph PowerShell SDK. Factors include:

  • The number of lines of code in the script.
  • The number of Azure AD cmdlets to replace.
  • How easy it is to replace a cmdlet. Microsoft publishes a cmdlet map to guide developers. The caveat is that sometimes the suggested SDK cmdlet generates different output to its Azure AD counterpart, meaning that some additional processing is necessary. Dealing with group members and owners are examples where changes are likely.

One thing’s for sure. The sooner an organization starts to inventory and upgrade its scripts, the sooner the work will be done and the less likely the effort will run into a time crunch when Microsoft deprecates the Azure AD and MSOL modules. Deprecation doesn’t mean that cmdlets necessarily stop working (some will, like the license management cmdlets). Support ceases and no further development of the deprecated modules happen, and that’s not a state you want for operational scripts. Time’s ebbing away…


So much change, all the time. It’s a challenge to stay abreast of all the updates Microsoft makes across Office 365. Subscribe to the Office 365 for IT Pros eBook to receive monthly insights into what happens, why it happens, and what changes to PowerShell modules mean for your tenant.

Windows Server détecte une batterie

Mini article pour les curieux !

Il m’est arrivé de me rendre compte sur l’un de mes serveurs Windows, que ce dernier affichait « Batterie en charge »… sauf qu’il s’agit d’un serveur au format rackable. Un peu étrange non ? Vérifiez par vous-même, vous risquez d’être surpris !

Bon pour ceux connaissant la réponse (mais au vu des nombreux posts dans les forums, ça ne semblait pas forcément tomber sous le sens), pas de magie noire ou de bug ici, simplement le fait que WS détecte l’UPS branché comme étant une batterie, et vous affiche donc sa charge et le pourcentage correspondant…

D’ailleurs, il existe une petite commande Powershell permettant de voir quelle(s) batterie(s) Windows détecte au juste :

 wmic path Win32_Battery get Caption,Description,DeviceID,Name

Bref, rien d’incroyable mais j’avoue que cela avait piqué ma curiosité !

Sur ce, à bientôt pour des articles (je vous rassure) plus fournis que celui-ci ! 😁

L’article Windows Server détecte une batterie est apparu en premier sur Notamax.

Adding New Azure AD Users to Groups Automatically

Dynamic Group Membership is the Obvious But Not the Only Option

A member of the Microsoft Technical Community asks if it’s possible to automatically add newly-created accounts to an existing group. The initial response offered by the community focused on dynamic groups – either dynamic distribution lists or dynamic Azure AD groups.

It’s a reasonable suggestion. Dynamic distribution groups are part of base Exchange Online functionality and don’t require any additional licenses. Dynamic Azure AD groups require Azure AD Premium P1 licenses for every account covered by dynamic membership. In both cases, the trick is to make sure that the query used by Exchange Online or Azure AD to determine group membership finds the new account.

Dynamic Group Membership for Exchange Online Mailboxes

It’s possible to create a dynamic distribution group based on a simple query like “all mailboxes” that will automatically include new accounts (if they have mailboxes). Figure 1 shows the UX in the Exchange admin center (EAC) to define the membership of a new dynamic distribution list.

Figure 1: Dynamic membership settings for all mailboxes

The list works and email sent to it arrives in the inbox of every mailbox in the tenant, including shared mailboxes. This is because the recipient filter generated by Exchange Online for the dynamic distribution group selects all mail-enabled objects with a recipient type of ‘UserMailbox’ and only filters out some system mailboxes.

A dynamic distribution list like this is said to use a “canned” recipient filter because Exchange Online generates the filter based on the choices the administrator makes when they create the new list. You can only edit canned filters through the EAC. Exchange Online gives greater flexibility through the support of custom recipient filters. These filters can only be created using PowerShell, but they’re much more flexible in terms of selecting the set of mail-enabled objects to address through the list. A simple custom recipient filter to find just user mailboxes is shown below together with a test with the Get-Recipient cmdlet to prove that the filter works.

$Filter = "{RecipientTypeDetails -eq 'UserMailbox'}"
Get-Recipient -RecipientPreviewFilter $Filter

Dynamic Group Membership for Azure AD User Accounts

Dynamic Azure AD groups can be used with Microsoft 365 groups and Teams. These groups use different membership filters (query rules) to find the set of target objects. Instead of mail-enabled objects like mailboxes, the query against Azure AD focuses on user accounts rather than mailboxes. However, the same capability exists in that it’s possible to create a dynamic Azure AD group that includes all user accounts, including those newly created.

Again, the key is to construct a query rule that finds all user accounts – of the right type. When Azure AD is used for a Microsoft 365 tenant, there are many non-interactive user accounts created to give identities to objects such as shared mailboxes and room mailboxes. These are all considered “member” accounts and it’s easy to build a rule to find all member accounts. However, you probably want a more refined version that finds just the accounts used by humans.

Azure AD doesn’t have a human filter, so we need to construct something that Azure AD can use to find matching accounts in its directory. One approach is to use licenses for the check. You could look for accounts assigned Office 365 E3 licenses but would have to check for accounts with F1 or E5 licenses too. An easy change is to look for accounts that have any license that has at least one enabled service. For instance, accounts with Office 365 E3 or E5 licenses with the Exchange Online, Teams, Planner, or SharePoint Online service would all match. Figure 2 shows a test of the rule against a “real” user account and some other user accounts belonging to room and shared mailboxes. You can see that the real account passes the validation test while the others do not.

Testing the membership rule for a dynamic Azure AD group to find all user accounts
Figure 2: Testing the membership rule for a dynamic Azure AD group to find all user accounts

Azure AD accounts used by shared mailboxes must be assigned licenses when they need more than 50 GB of mailbox storage or an online archive. These accounts satisfy the membership rule, but that’s perhaps not important. If it is, some tweaking of the membership rule is necessary to remove the shared mailbox accounts.

Dynamic Group Membership of Org-Wide Teams

If your organization is smaller than 10,000 accounts, new Azure AD accounts automatically join the org-wide teams in the tenant (a tenant can support up to five org-wide teams). Org-wide teams are a special form of dynamic Microsoft 365 group whose membership is controlled by Teams rather than Azure AD, so Azure AD Premium P1 license are not required.

The PowerShell Alternative to Manage Dynamic Group Membership

If you don’t want to use a dynamic object, it’s certainly possible to use standard distribution lists or Microsoft 35 groups. In this scenario, the tenant takes the responsibility for maintaining group membership. Usually, PowerShell is used to add new accounts to group membership. You don’t have to worry about removing deleted accounts from the group as this happens automatically following an account deletion.

To add a new user to a distribution list, use the Add-DistributionGroupMember cmdlet:

Add-DistributionGroupMember -Identity "All Tenant Mailboxes" -Member Lotte.Vetler@office365itpros.com

To add a new user account to a Microsoft 365 group, either run the Add-UnifiedGroupLinks cmdlet (from the Exchange Online management module) or the New-MgGroupMember cmdlet (from the Microsoft Graph PowerShell SDK):

Add-UnifiedGroupLinks -Identity "All Tenant Accounts" -LinkType Member -Links Lotte.Vetler@office365itpros.com

New-MgGroupMember -GroupId "107fe4dd-809c-4ec9-a3a1-ab88c96e0a5e" -DirectoryObjectId (Get-MgUser -UserId Lotte.Vetler@office365itpros.com).Id

If the tenant creates user accounts programmatically with PowerShell, these commands can be added to that script. If not, a background scheduled job could find accounts that don’t exist in group membership and add them. See this article for more information about group management with the Microsoft Graph PowerShell SDK.

Many Possibilities to Ponder

A simple question required a long answer. That’s because the questioner didn’t specify what type of group that they wanted to add new accounts to. In any case, it’s nice to be able to debate the possibilities and then settle on the best course of action to take.


Insight about the various options to manage dynamic group membership for new accounts 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.

Get All the Public or Private Team Sites in SharePoint with PnP.PowerShell

When you create a Team Site in SharePoint, you have an option to set the Team Site as:

  • Public – anyone in the organization can access this site, or
  • Private – only members can access this site

Many people don’t know what the effect this setting has – I need to remind myself from time to time.

Private means the site is not discoverable; only people who are assigned specific permissions for the site can find it – even if they happen to guess the URL. Private Team Sites make sense when even knowing the name of the Team Site might be problematic. “Surprise Birthday Party” or “Firing People” come to mind.

Public means the site is discoverable; anyone in the organization can find the site using search or even just guessing the URL. More important, when you create a site as Public, the Everyone except external users pseudogroup is added to the Members for the site. This means every licensed user can add and edit content – unless you change the permission settings.

If any of the above is a surprise to you, well I’m not surprised by that. I don’t think the wording on the Create site dialog is all that clear, and unless I’m missing something, I can’t find a Microsoft article which explains it in the amount of detail I give above.

If you’d like to know what the setting is for any particular site, here’s how you’ll know. As of this writing (it’s moved around a bit in the past and can vary based on your header settings for the site), you can tell if a site you’re visiting is Public or Private by looking in the upper right on the home page:

That’s well and good if you have a site or two to check. But what if you’d like to know how all your sites are set up? Time to turn to trusty PnP.PowerShell. I needed to do this today and it was really hard to figure out where the setting was available. Turns out, it’s not a setting on the site itself, but on the underlying Microsoft 365 Group.

Once I knew that, easy-peasy.

This single line of PnP.PowerShell will retrieve all the Microsoft 365 Groups where the Visibility property is set to Private. If you want the Public sites, well I’ll leave that to you, dear reader.

Get-PnPMicrosoft365Group -IncludeSiteUrl | Where-Object { $_.Visibility -eq "Private"}

Of course, you’ll need the appropriate permissions and you’ll need to have connected to the SharePoint Admin site with Connect-PnPOnline first.


If you’d rather not use PowerShell (and Todd will be offended of you don’t!), you can also see this setting in the Exchange admin center (microsoft.com) in the Groups listing. That listing can be exported to Excel if you’d like to do more slicing and dicing.

References

❌
❌