Page 2 of 8

Applying Microsoft Teams Naming Standard

In this blog post, we will learn how to apply naming conventions to our teams. As large organizations have special needs on what teams’ names would be in order to easily manage them, it’s essential for teams admins and even anyone who is working professionally with Microsoft 365 to know how it’s done.

The ability to apply naming convention to Microsoft Teams is done by applying a naming policy on groups in Azure. Once the policy is applied on the groups then any newly created team will be constrained by these rules. Any existing Microsoft Teams won’t be affected by these rules. Also note that in order to make this work, you will need to have Azure AD Premium P1 license (or EDU license).

Let’s have a fun scenario and say that in our organization, we would love that all newly created teams to be named as: Accountants-[Team Name] or Teams Developers-[Team Name]. Meaning that they should be prefixed by the person’s title + s-. How can this be done? This can be done by having a combination of an attribute prefix combined with a string prefix. So the combination of both would give us something such as [Job Title]s-[Team Name]. Note that I added an s to the job title as another prefix to achieve the s in Developers or Accountants.

In order to apply this policy, go to Microsoft Azure (portal.azure.com), and navigate to Azure Active Directory > Groups  > Naming Policy

On the first tab, you can specify words that you want to be prevented from being part of your Team’s name. You can download the csv file, populate it with the required words, and reupload it again. Note that it’s not case sensitive, so if you add the word tips, TIPS will also be prevented from appearing in the team’s name, however tipss will be allowed.

Now click on the next tab that says Group naming policy, and here you can see we have 2 types, we have prefix and suffix, and under each one we can specify the policy to be based on free text (String) or based on user’s attribute. The attributes supported are shown in the dropdown list:

Note that not all user’s properties are supported and only 6 of them are at the time of this writing. Now to achieve our goal, we’ll have the first prefix as Attribute = Title, and the second prefix as s- so our newly created team would look like: Accountants-TeamName

Note that the prefixes and suffixes are applied in the order they’re listed here, by appending the latter to the previous prefix. Now save the changes and try to create a team. If you get an error like the one showed below that says: “The team prefix or suffix is incorrect, please try again”:

Don’t worry, as it takes some time for the changes to be applied. In my case it took around 10-15 minutes. Also note that if you’re testing with a global admin account then you won’t be affected by these policies and you can create teams with whatever names you want.

So with a regular user who’s title is Retail Manager, when creating a team, it will look like this for a team named Client Support:

The catch here is that this naming policy is done on the Azure groups themselves, which means if we try to create groups from another service, let’s say in Outlook, we’ll have the same constraints applied there as well:

Microsoft 365 & SharePoint Languages Explained

Users in Microsoft 365 (even experienced ones) often get confused as how languages work across the platform. This an important topic specially for organizations that operate across multiple countries, or in countries that have 2 official languages.

There are many areas where a language can be specified in Microsoft 365, and they can be grouped in 3 categories:

  • Group A: Services whos language can be changed in Account Settings.
  • Group B: Services who language can be changed in Delve.
  • Group C: Free For All. (Each service has its own way of setting the language).

We’ll be looking at each one of these categories, and then dig deeper into the new multilingual capabilities of SharePoint.

Group A (Account Settings): These services depend on the current user’s account settings to determine the language. If you login to Microsoft landing page: Office.com, and you want to change the language for that page or the language being used for Forms, Planner, Word Online, Excel Online. Then you need to do this using the account settings of Microsoft 365. To do this, you can follow these steps:

  • Click on your profile image, and click account settings:

  • Next, from “Settings & Privacy” section, click on Languages > Display language. (The display language is the one that is used to change the labels across the platform). Here you can assign the preferred language.

Group B (Delve): To change the language for SharePoint and OneDrive, the process is a bit more involved. There are 2 locations where the user can set the language, either on their browser or in Microsoft Delve. Delve has more priority than the browser language settings, meaning that if the user set their Delve settings to French, SharePoint sites will display in French (if French is supported on the site). If the user hasn’t specified a language in Delve, SharePoint will look for a preferred language in the browser settings. If the user hasn’t set a preferred language in both Delve and the browser, the site will be displayed in its default language.

For quick tests for SharePoint multilingual pages, it’s best to use the browser settings as it’s very quick to reflect the changes. Changing the language in Delve will take around 10 minutes to take effect. To change the language in browser will depend on the browser itself, but for Chrome and Edge, it’s done by clicking on the options menu:

Then searching for “languages”, there we can set our preferred language. OneDrive will pick up this change and will be displayed in the browser language if Delve has no default language (remember Delve has more priority). To change the language in Delve, you can refer to this article: https://support.microsoft.com/en-us/office/change-your-personal-language-and-region-settings-caa1fccc-bcdb-42f3-9e5b-45957647ffd7

Group C (Free For All): Services in this group have their own ways to change languages. For example, Teams will allow you to change the language while using Teams client. Stream will allow to change the languages in Stream itself and same for other services in this category.

In the next post, we will see how multilingual sites work in SharePoint and how they’re affected by the settings discussed in this post (Group B). Till the next time!

Working with XML & PnP Provisioning

If you work with PnP Provisioning Engine that much, you might reach a point where you want to have your configuration sitting in an XML file, and read its settings and pass it to your provisioning engine. However, you might run into some issues when dealing with special characters if you try for example to name your sites something such as “R&D”.

We’ll have a look at a case. Let’s say you have an XML configuration file named config.xml, that contains some settings regarding site urls and site names that you want to use in your provisioning engine. One of the values in XML might look like this:

Config.XML

If you try to read its value like this:

Reading XML file with PowerShell

You’ll end up with such an error:

Cannot convert value “System.Object[]” to type “System.Xml.XmlDocument”. Error: “‘<‘ is an unexpected token. The expected token is ‘;’

This means, that we’ll need to encode our value in XML, so we’ll end up with something like this:

Encoding values in XML

Or we can keep the value is XML as R&D, and replace the & with &amp; in our PowerShell script like the following:

Getting XML as string then replacing invalid characters


Now when we get the right value from $Config in PowerShell, it works just fine, and we’ll have a string as “R&D”. However, when we pass this value to our provisioning template:

It will complain again with such an error:

‘ ‘ is an unexpected token. The expected token is ‘;’.

The reason is, when it’s passed from PowerShell as “R&D” to the provisioning engine, it has to be encoded one more time. To do so, we’ll need to execute this before passing our values to the provisioning engine:

[System.Web.HttpUtility]::HtmlEncode($config.parameters.SiteTitle)

We store this in a variable, and pass it as a parameter to our provisioning engine. It will work like a charm!

Sharing Excel Sheet On A SharePoint Page (Or any web page)

You might come across a requirement to share an excel file on any page, or even on a SharePoint page (either on prem or online). Considering the options that would be available, and since we want to share an excel file, so why not using Excel online?

To do this, we can upload our document to either OneDrive or SharePoint online, since both of them will use Excel online to work with the Excel document. Once we do that, we can open our Excel document, then click File > Share > Embed:

In the page that appears you have many options to control the rendering of your excel file, the end result will be an iframe HTML element that you can copy and paste in any page you need (Even any site accessed anonymously).

ONE CATCH: The option to “Let people sort and filter” will provide you with the headers to sort and filter column, but it will also provide you with a refresh button at the bottom of the sheet:

HOWEVER, if you update the data in your workbook and you click on this button it won’t refresh the data. From what I’ve seen, it takes around 5 minutes to refresh the data in this embedded sheet from the actual data source. This button will serve well if you stay on that page for 5 minutes then click it. Otherwise, a page refresh will just give you the updated data after the minutes. So if you change the data in your excel file and don’t see them updated right away, don’t panic, wait a bit then refresh the page.

Now to embed this in a SharePoint on prem page, you can just use the script editor web part, for SharePoint online, you can edit the page, and from the list of web parts choose Embed:

Which is similar to the SharePoint on prem way of embedding the code. There you can just paste the iframe code you got from Excel.

Easily validate Power Apps dates

In this post we’ll see how easily to validate date pickers in Power Apps. Right now am working on an application to help the IT team schedule the deployments for Office ProPlus (Microsoft 365 apps for enterprise) and Teams to users. I’d like to send an email to users asking them if the proposed date is good for them plus other questions that they can deal with in a Power Apps application, if not, they can reschedule. However, I want that when they reschedule for it to be at least 7 days from now so the IT team can have the time to prepare for the deployment and bundle multiple computers together. Also, I want to prevent users from choosing a weekend day. So how to do that? The formula for this would be too short and simple if we understand how to approach it.

First when we choose a date from the picker and click on the submit button, I will have a formula to update a context variable named “isValid”. What I’ll do is, to check if the difference between the selected data and today’s date is less than 7 days. I’ll do that with the DateDiff function, which acts like the following:

Second argument – First argument = Number of days.

This function will return the difference in days between the two dates, so we can check if it’s > 7. Note, this will also validate if the date is in the past as well, since if the date is less than today’s date, the result will be in the minus.

If it’s more than 7 days, we check for weekends. I will be using the Weekday function to determine if the selected date is equal to 1 (Sunday) or 7 (Saturday). To connect all the checks together so they’re all truthy, I’ll be using And operator between all checks, so the final formula would look like this:

UpdateContext({isValid: If((DateDiff(Today(), txtNewDate.SelectedDate, Days) > 7) And (Weekday(txtNewDate.SelectedDate) <> 1) And (Weekday(txtNewDate.SelectedDate) <> 7) , true , false)});       

Few handy functions here and there, to make powerful little formula.

Quick Tip – Power Apps on Android – “Pick an account to continue”

This one is going to be quick, but it took me a bit to figure it out. I am connecting to multiple Power Apps environments with the same phone across multiple tenants. Recently I started getting this issue whenever I open Power Apps on the phone I am returned to a screen showing me all my email accounts across tenants and it says: “Pick an account to continue”. When I choose an account, it shows the Apps list for a second, then it goes back to “Pick an account to continue” screen… which is frustrating.

I thought it’s an issue with Power Apps caching, so I deleted the cache. didn’t work… I deleted all Power Apps data, didn’t work. Then I found the best solution! Uninstall-Reinstall Power Apps… but yup that didn’t work either. How is Android remembering all these emails while I have been clearing the data all the time?

Turns out that this data is stored at this location: Settings > Users & Accounts > Work Account.

When I opened that screen, I saw all those junk emails sitting there and that’s where Power Apps mobile is reading the emails from. I cleaned up the emails and kept only the one I need.

Seems like Power Apps on Android doesn’t really handle multiple accounts that well. Since I tried later to add another account, it worked fine. Then I signed out of that account and tried in to sign in with another one, kept getting errors about “Sign in with work or school email is required”.

Best way I saw to solve this issue, is after signing out from a specific account with PowerApps, close the application, open it again and sign in with the new account.

Remember to clean up the accounts stored in your device, then have the habit of restarting the app after signing out.

In case you’re not working with multiple accounts in Power Apps, forget everything you read in this article!

Query Microsoft 365 subscriptions with PowerShell

There are 2 main PowerShell modules for managing Azure AD (and access O365 licenses): AzureAD module and MSOnline module. (There are 2 more modules for AzureAD for preview, but I haven’t worked with them yet).

Let’s say that you want to get all users in a specific office, who have O365 licenses? We can do something like this:

We can do something like this:

Get-AzureADUser  -all $true  | Where { $_.PhysicalDeliveryOfficeName  -eq ‘Office Name’ -and $_.AssignedLicenses -ne $null} | select UserPrincipalName , DisplayName | export-csv [AddCsvPath]

That might work, but.. it might also give you more results than what’s expected. What if some users use PowerBI (Free), Flow (Free) or Teams Exploratory license (free Teams license for those who aren’t yet assigned a license).

If you run the previous command, it will get those users too since their AssignedLicenses isn’t actually null.

To do that, let’s first query all O365 available licenses in our tenant and see what we get. We can run something like the following:

Get-AzureADSubscribedSku

You’ll get a result of ObjectId and SkuPartNumber, the SkuPartNumber is the description for the licenses, and the ObjectId will be formatted like this: [TenantID]_[LicenseId]

For example, for the E5 license, the SkuPartNumber is SPE_E5, and the ObjectId is:

[GUID FOR TENANT]_06ebc4ee-1bb5-47dd-8120-11324bc54e06

Now that we know the license ID exactly, we can use it to get users in the required office, with the required license ID:

Get-AzureADUser  -all $true  | Where { $_.PhysicalDeliveryOfficeName  -eq ‘Office Name’ -and ($_.AssignedLicenses).SkuId -eq "06ebc4ee-1bb5-47dd-8120-11324bc54e06"}  | export-csv [AddCsvPath]

For reference, here are some of the most common license information that you might need:

NameID
E118181a46-0d4e-45cd-891e-60aabd171b4e
E305e9a617-0261-4cee-bb44-138d3ef5d965
E506ebc4ee-1bb5-47dd-8120-11324bc54e06
E5 Developer Licensec42b9cae-ea4f-4ab7-9717-81576235ccac
TEAMS Exploratory710779e8-3d4a-4c88-adb9-386c958d1fdf
Teams Commercial29a2f828-8f39-4837-b8ff-c957e86abe3c
Flow Freef30db892-07e9-47e9-837c-80727f46fd3d

This list will only save you time executing Get-AzureADSubscribedSku !


Restrict Yammer Groups Creation

Yammer is an awesome tool to have company-wide communications. With open communities that people can join and interact with each other without having to work with each other on a daily basis. It’s a perfect network where people can reach out together, interact with the upper management, and share thoughts across the whole organization.

The bad thing about Yammer however, is by default it would allow everyone in the company to create Groups (newly named as Communities), and there’s no way by default for a Yammer admin to restrict the creation of these communities to be just for a subset of people. So how can we do it?

Knowing that the creation of Microsoft 365 groups creation can be restricted, so why not making Yammer follow the same policies as Microsoft 365?

Let’s have one step back and see the restriction on creating new Microsoft 365 groups. To restrict the creation of new groups in M365, you’d have follow steps mentioned in this article:

https://docs.microsoft.com/en-us/microsoft-365/admin/create-groups/manage-creation-of-groups?view=o365-worldwide

Basically, you’ll need to creation a group in Azure AD, and use Azure AD PowerShell module to restrict the creation of new groups to only this security group as the article describes:

$GroupName = "[AddSecurityGroupNameHere]"
$AllowGroupCreation = "False"

Connect-AzureAD

$settingsObjectID = (Get-AzureADDirectorySetting | Where-object -Property Displayname -Value "Group.Unified" -EQ).id

if(!$settingsObjectID)
{
$template = Get-AzureADDirectorySettingTemplate | Where-object {$_.displayname -eq "group.unified"}
$settingsCopy = $template.CreateDirectorySetting()
New-AzureADDirectorySetting -DirectorySetting $settingsCopy
$settingsObjectID = (Get-AzureADDirectorySetting | Where-object -Property Displayname -Value "Group.Unified" -EQ).id
}

$settingsCopy = Get-AzureADDirectorySetting -Id $settingsObjectID
$settingsCopy["EnableGroupCreation"] = $AllowGroupCreation


if($GroupName){
$settingsCopy["GroupCreationAllowedGroupId"] = (Get-AzureADGroup -Filter "DisplayName eq '$GroupName'").objectId
}

else {
$settingsCopy["GroupCreationAllowedGroupId"] = $GroupName}
Set-AzureADDirectorySetting -Id $settingsObjectID -DirectorySetting $settingsCopy
}

This is exactly the same code mentioned in the article, just make sure to have the correct group name you created in M365 that contains people who are allowed to create groups (Make sure to add the required people as members, adding them as owners only won’t grant them permissions to create M365 groups)

Now that we managed to have a security group whose members are allowed to create M365 groups. We’ll need to let Yammer follow same rules as M365. For that, we’ll have to put Yammer in Native Mode for M365. So what’s the native mode for M365 in Yammer?

The native mode is a way for Yammer to follow same rules of M365, so the documents will be stored in SharePoint online. The creation of a new Yammer community (group) will result in the creation of a new M365 group, you can search for Yammer content in the M365 security and compliance center.

So how do we put Yammer in native mode for M365? First we’ll need to enforce O365 identity in Yammer, which basically tells Yammer to let users login with their O365 accounts (which makes sense since you’d want them to login to Yammer that way). You do this step by going to Yammer admin page, and on the left menu under “Content and Security” click on “Security Settings”. Make sure to have “Enforce Office 365 identity”:

Now after enforcing O365 identity, we’ll finally tell Yammer to follow same rules as M365, but putting it in native mode for M365, to do so go to “M365 Native Mode” from the left menu in the Yammer admin page. You’d have to generate the Alignment Report. This report will show any warnings in case some users won’t be able to exist in the network if it’s migrated to the new mode, or if some old groups are available that aren’t already connected to O365 groups.

Old groups will have O365 groups provisioned and connected to them. If you have any naming convention policies for M365 groups, they won’t be applied in this case for these existing Yammer groups.

After running the alignment report, you can download it, I opened it in vscode like this:

and the page will be updated to show you the results of the analysis:

At the very end of the page, you confirm that you want to proceed with the conversion, the reason for that is that this change won’t be rolled back, once you go Native Mode, that’s it.

Now users who aren’t allowed to add a community (group), won’t see this option in Yammer:

The new Yammer experience, without being able to add a new community

Managing Teams Private Channels With PowerShell

In the previous post we talked about the need to upgrade to TLS 1.2 to install PowerShell modules related to Office 365.

When using this method, specifically for Microsoft Teams, it will install a module where you won’t be able to execute commands related to private channels, such as the -MembershipType parameter when creating a new channel using the New-TeamChannel command.

To do this, we’ll need to install the Teams module from the PowerShell Test Gallery instead: https://www.poshtestgallery.com/

When going to that website, you’ll notice that the most known module there is the Microsoft Teams module, which as of now, had around 9,200 downloads in the last 6 weeks. To install this module, you would to remove the existing Teams Module if you already had it installed:

Uninstall-Module -Name MicrosoftTeams 

Then we’ll need to register the test gallery with PowerShell so we can use it later when we do installations, note the name of the gallery you choose to be used in PowerShell can be anything you like, for me I chose PSTG, short for PowerShell Test Gallery:

Register-PSRepository -Name PSTG-SourceLocation https://poshtestgallery.com -InstallationPolicy Trusted


Then we can install Teams module again:

Install-module -Name MicrosoftTeams -Repository PSTG -Force

Now you’re ready to go.

Common issues you might face:

1- If you get an error that the MicrosoftTeams module is already in use and you can’t remove it, just restart the PowerShell session.

2- If you get an error with something like:


The specified uri ‘https://www.poshtestgallery.com’ for parameter ‘SourceLocation’ is an invalid web uri. Please ensure that it meets the Web Uri Requirements.


Then it’s the same case as the previous post, where you need to set the PowerShell session to run on TLS 1.2, so commands will be like:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 

Register-PSRepository -Name PSTG -SourceLocation https://poshtestgallery.com -InstallationPolicy Trusted

April-2020 TLS Upgrade Needed for PowerShellGet

When trying to install any PowerShell module to work with Microsoft 365 (such as AzureAD v1, AzureAD v2, Teams, Exchange Online, SharePoint), I got the following issue:

WARNING: Source Location ‘https://www.powershellgallery.com/api/v2/package/PackageManagement/1.4.7’ is not valid. PackageManagement\Install-Package : Package ‘PackageManagement’ failed to download. At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1:1809 char:21 + … $null = PackageManagement\Install-Package @PSBoundParameters + ~~~~ + CategoryInfo : ResourceUnavailable: (C:\Users\mderha…anagement.nupkg:String) [Install-Package], Exception + FullyQualifiedErrorId : PackageFailedInstallOrDownload,Microsoft.PowerShell.PackageManagement.Cmdlets.InstallPackage

The reason is that the PowerShell gallery has deprecated the support for TLS 1.0 and 1.1 in April 2020. So an upgrade needs to take place for the PowerShellGet module to support TLS 1.2 (or later version).

RESOLUTION

The following commands needs to be executed to update PowershellGet.

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12  
Install-Module PowerShellGet -RequiredVersion 2.2.4 -SkipPublisherCheck 

Now you can install other modules for Teams, Azure, etc 

  • AzureAD v2:  Install-Module -Name AzureAD 
  • AzureAD v1:  Install-Module –Name MSOnline 
  • Teams:  Install-Module -Name MicrosoftTeams 
  • SharePoint:  Install-Module  Microsoft.Online.SharePoint.PowerShell 
  • Exchange Online: Install-Module -Name ExchangeOnlineManagement
  • Skype for business: https://www.microsoft.com/en-us/download/details.aspx?id=39366 

Here’s the list of modules related to Microsoft for reference:

To update a module:

Install-Module Microsoft.Online.SharePoint.PowerShell -force


AzureAD v1 still has richer commands, but AzureAD v2 will be the recommended one later. You can have both installed at the same time.