Category Archives: Office 365

SPFx-People-Search

SharePoint/SPFx: Returning to Webpart Development Part #4 (with React Hooks)

Recently I was asked to develop a webpart for a modern SharePoint site. My first thoughts, where do I start; I haven’t done any webpart development for years? I would like to share my journey with you over the next few posts and hope my experience will help new and returning developers along the way.

In my previous post I covered:

In this post I will cover:

This article is different to its predecessors in the series, because I have published the SPFx-People-Search webpart solution to my GuiHub repository, I will be focusing on what I have found challenging about writing this webpart with React Hooks, SPFx and Microsoft Graph.

In the previous article I created the Project Folder Structure with stub files ready to add code. So now I can focus on creating the components such as the Service and User Interface. I deliberated on where to start, creating the Service layer or UI. Deciding to start with a service class called MSGraphService.ts and its corresponding interface.

Note: I have added a data JSON file, however I have more work to do before this can be used for testing in the local workbench.

Service Layer

The MSGraphService is based upon the Service Locator pattern which I took inspiration from an old colleague Vardhaman Deshpande who wrote this article. The MSGraphService files are located here:

Having decided on this pattern and how to implement it, the other challenges I had with the Microsoft Graph API included:

Microsoft Graph User Photo

What to do with the data returned by Microsoft Graph User Photo endpoint. With the lack of documentation, the Graph Explorer is great, but it still took a bit of work to figure out what to do with “Blob Strings” …

Microsoft Graph Explorer Me/User Photo
https://developer.microsoft.com/en-us/graph/graph-explorer?request=me%2Fphoto%2F%24value&method=GET&version=v1.0

See the getUserPhoto() function located within MSGraphService.ts

User Presence

What the different User Presence options are: User may display…? Again, the Graph Explorer was a great help, it went a long way to making up for the lack of documentation.

Microsoft Graph Explorer Me/User Presence
https://developer.microsoft.com/en-us/graph/graph-explorer?request=me%2Fpresence&method=GET&version=beta

See the getUserPresence() function located within MSGraphService.ts and the implementation within ResultCard.tsx

Configure the API permissions requests

This time I can praise the documentation by Microsoft: “To consume Microsoft Graph or any other third-party REST API, you need to explicitly declare the permission requirements from an OAuth perspective in the manifest of your solution.” For more information see https://docs.microsoft.com/en-us/sharepoint/dev/spfx/use-aad-tutorial#configure-the-api-permissions-requests

And my working example of the package-solution.json can be found here: https://github.com/sionjlewis/SPFx-People-Search/blob/main/config/package-solution.json

User Interface

To keep things simple, I kept the PeopleSearchWebPart.ts webparts “main/entry” class, created by the SPFx Yeoman scaffold, pretty much “as is”. Converting this class to React Hook seemed to be more hassle that it was worth.

Using React Hooks with the SPFx framework

So unlike all the React.JS Hook Documentation, I was unable to implement a basic function, but instead I found I needed to write something similar to the following:

export const PeopleSearch: React.FunctionComponent<IPeopleSearchProps> = (props) => { 
    … 
};

Writing the Hooks

Having organised the components into a Project Folder Structure, I started at the top:

  1. Added references and initiated object to PeopleSearchWebPart.ts and passed them on to PeopleSearch.tsx
  2. Updated the IPeopleSearchProps.tsx interface and added each of the “Wrapper” Hooks to the return statement
  3. Focusing on the ResultWrapper, I added the “useState” and “useEffect” Hooks to handle the getFilteredUsersExpanded() data, which I then “mapped” instances of the ResultCard.tsx
  4. Before focusing on details such as User Presence and User Photo, I output the “raw” User data to the user interface from the return statement. I used this technique to confirm that the service layer was connecting to and returning the data as expected

I continued on with this process of working until I “finished” the Results components and then moved onto the Footer and Search components.

You may have noticed that I have not started on the filter components as my strategy is to get something working as quickly as possible, with the following goals:

  • Enables demos and feedback loop to start earlier
  • Test the API(s) to confirm that they work as expected (or documented) and update our strategy if they don’t

Other Stuff

underscore.js vs Lodash

Back in my “JavaScript” days I was a big fan of underscore.js, so I tried it within this project, however I found the library too cumbersome to import and so I ended up replacing it with Lodash which seems to play better with TypeScript.

Conclusion

I am now a self-confessed fan of React Hooks and have really enjoyed the process of building this webpart. As with any new development technique or process, I will find better ways of doing things as I do more, but I like how clean the code looks and reckon the modularity will make the solution so much easier to support.

Windows PowerShell ISE

Configuring SharePoint & Microsoft Teams PowerShell environment

Here is a list of steps that I usually complete when configuring a PC, so that I can run PowerShell script that connects to SharePoint Online and Microsoft Teams.

SharePoint Online Client Components SDK

The SharePoint Online Client Components SDK can be used to enable development with SharePoint Online. …[Microsoft] recommend using NuGet packages rather than installing CSOM assemblies to GAC. However, I find these DLLs useful when writing CSOM directly within my PowerShell scripts. 

Click here to select and download the relevant MSI file.

Open Windows PowerShell ISE as Administrator

To be able to complete the other steps that follow, we need to run the Windows PowerShell ISE as Administrator. If you would like to make this a more “permanent” action, follow these steps:

  • Search for Windows PowerShell ISE and Pin to the Start menu
  • Right click on the pinned tile and click on More and Open file location
  • Locate the Windows PowerShell ISE shortcut, right-click and select Properties 
  • Click Advanced… and select Run as administrator
  • Finish by clicking OK, Apply and OK 

From now on, when opening the Windows PowerShell ISE application from the Start menu, you will be prompted by: “Do you want this App to change your device.” Don’t forget to click Yes.

Note: If you do not open Windows PowerShell ISE with “Run as Administrator” you will not be able to set the Execution Policies. 

Check Your PowerShell Version 

The Microsoft Teams PowerShell Module has some known issues with PowerShell 7.
For the best experience, [Microsoft] recommend that you use PowerShell 5.1. If we are running anything newer than 5.x then you may need to down-grade… 

Run the following PowerShell code to check the PowerShell version

Get-Host | Select-Object Version; 

Execution Policies 

Generally, the execution policies on new machines are set to a level that will restrict the installation and running of our scripts. See the About Execution Policies article for information on how to manage them. Running the following PowerShell cmdlet to see what your current Execution Policy is set to:

Get-ExecutionPolicy;

I usually set my Execution Policy to Unrestricted, by running the following PowerShell cmdlet:

Set-ExecutionPolicy -ExecutionPolicy Unrestricted; 

Install SharePoint Online Management Shell 

The SharePoint Online Management Shell is a tool that contains a Windows PowerShell Module to manage your SharePoint Online subscription in Office 365. 

I would recommend using the PowerShell cmdlet instead of the .MSI files, as the process for updating modules later are simpler. Click here for more information about the SharePoint Online Management Shell.

Run the following cmdlet, in administrative mode, to see if the SharePoint Online Management Shell has already been installed:

Get-Module -Name Microsoft.Online.SharePoint.PowerShell -ListAvailable | Select Name,Version;

Or run the following cmdlet, in administrative mode, to install the latest version of the SharePoint Online Management Shell:

Install-Module -Name Microsoft.Online.SharePoint.PowerShell;

Install PnP PowerShell Library

SharePoint Patterns and Practices (PnP) contains a library of PowerShell commands (PnP PowerShell) that allows you to perform complex provisioning and artifact management actions towards SharePoint. The commands use CSOM and can work against both SharePoint Online and SharePoint On-Premises (depending on the modules installed)

Click here for more information or run the following cmdlet to install the SharePoint Online PnP PowerShell library:

Install-Module SharePointPnPPowerShellOnline;

Install Microsoft Teams PowerShell

Microsoft Teams PowerShell is a set of cmdlets for managing Teams directly from the PowerShell command line.

Warning: There are known issues with PowerShell 7 and Teams PowerShell. For the best experience, we recommend that you use PowerShell 5.1.

Click here for more information or run the following cmdlet to install the Microsoft Teams library:

Install-Module MicrosoftTeams; 

Upgrading PowerShell Libraries

As a rule, I avoid using the Update-Module cmdlet as this results in having multiple versions of the same library installed. Instead, I like to use the Uninstall-Module cmdlet before then installing the latest version.

Connect-PnPOnline: unwanted credential caching

UPDATE: May 2021

This problem, as described in my original post below, has been fixed for the Connnect-PnPOnline, when using the UseWebLogin param. Plus, the ClearTokenCache parameter is no longer available…

Connect-PnPOnline -Url "https://[tenant].sharepoint.com" -UseWebLogin; 

The “new” (or orignal) experience when calling the above Cmdlet will look like the following screen shot:

Login screen: That didn’t work … Here are a few ideas…

For more options, see https://pnp.github.io/powershell/cmdlets/Connect-PnPOnline.html#example-9

An alternative is to use the Interactive prameter:

Connect-PnPOnline -Url "https://[tenant].sharepoint.com" -Interactive; 

For more information, see https://pnp.github.io/powershell/cmdlets/Connect-PnPOnline.html#example-10

Original Post

Since creating a new Windows 10 profile (new PC) the Connect-PnPOnline PowerShell CmdLet has been caching my primary credentials while using the UseWebLogin parameter.

Connect-PnPOnline -Url "https://[tenant].sharepoint.com" -UseWebLogin; 

This wouldn’t be a problem if I only worked with on tenant…

After a fair amount of Google searching, mucking around with Internet Explorer and Microsoft Edge settings I found that running the Connect-PnPOnline CmdLet with the following parameters worked:

Connect-PnPOnline -Url "https://[tenant].sharepoint.com" -SPOManagementShell -ClearTokenCache;

Once signed you can revert back to using the UseWebLogin parameter, well until the next time the PowerShell console caches the wrong details… 😉

For more information see: https://docs.microsoft.com/en-us/powershell/module/sharepoint-pnp/connect-pnponline?view=sharepoint-ps

Office 365 Service Health

Need to check the health of your Office 365 Tenant and Services?
Here are some links that may help:

Office 365 (Tenant) Service health
https://portal.office.com/adminportal/home#/servicehealth

Microsoft 365 Service health status
https://status.office365.com

Office 365 outage map
https://downdetector.co.nz/status/office-365/map

Manage the life cycle of private channels in Microsoft Teams

Microsoft has published a very useful article in “Manage the life cycle of private channels in Microsoft Teams”, which can be found here: https://docs.microsoft.com/en-us/microsoftteams/private-channels-life-cycle-management

In this post I have added my thoughts below some of their key points.

Set whether team members can create private channels

Team owners can turn off or turn on the ability for members to create private channels in team settings. To do this, on the Settings tab for the team, turn off or turn on Allow members to create private channels.

Microsoft
Microsoft Teams: Team Settings

As an admin, you can use Graph API, however currently there is not an option available for PowerShell (e.g. using the Set-Team PowerShell cmdlet – version 1.0.3).

Set whether users in your organization can create private channels

As an admin, you can set policies by using the Microsoft Teams admin center or PowerShell to control which users in your organization are allowed to create private channels.

Using the Microsoft Teams admin center

Use teams policies to set which users in your organization are allowed to create private channels. To learn more: https://docs.microsoft.com/en-us/microsoftteams/teams-policies

Microsoft

Using PowerShell

Use CsTeamsChannelsPolicy to set which users in your organization are allowed to create private channels. Set the AllowPrivateChannelCreation parameter to true to allow users who are assigned the policy to create private channels. Setting the parameter to false turns off the ability to create private channels for users who are assigned the policy.

Microsoft

NOTE: This cmdlet is currently (20/11/2019) only available in limited preview in the pre-release Teams PowerShell module.

Create a private channel on behalf of a team owner

As an admin, you can use PowerShell or Graph API to create a private channel on behalf of a team owner. For example, you may want to do this if your organization wants to centralize creation of private channels.

Microsoft

Pretty straight forward, for more information see the links below:

Find SharePoint URLs for all private channels in a team

Whether you’re looking to perform eDiscovery or legal hold on files in a private channel or looking to build a line-of-business app that places files in specific private channels, you’ll want a way to query the unique SharePoint site collections that are created for each private channel.

As an admin, you can use PowerShell or Graph APIs commands to query these URLs.

Microsoft
$sites = get-sposite -template "teamchannel#0" 
$groupID = “<group_id>" 
foreach ($site in $sites) {
  $x= Get-SpoSite -Identity $site.url -Detail; 
  if ($x.RelatedGroupId -eq $groupID) {
    $x.RelatedGroupId;$x.url
  }
} 
GET https://graph.microsoft.com/beta/teams/<group_id>/channels?$filter=membershipType   eq 'private'    

Compliance, eDiscovery and legal hold are all very important considerations when working with SharePoint and Microsoft Teams and I don’t see Private Channels being different. With that in mind, being able to quickly locate and manage the Site Collections (and data) is essential.

Currently there is not way to list and manage site collections created by Private Channel within the SharePoint Admin Center. Plus the PowerShell implementation is lagging behind the Graph API. That said with a little effort we can work around these limitations.

List and update roles of owners and members in a private channel

You may want to list out the owners and members of a private channel to decide whether you need to promote certain members of the private channel to an owner. This can happen when you have owners of private channels who have left the organization and the private channel requires admin help to claim ownership of the channel.

As an admin, you can use PowerShell or Graph APIs commands to query these URLs.

Microsoft

Pretty straight forward, for more information see the links below:

Microsoft Teams: Team Settings

First impressions of Private Channels in Microsoft Teams

We finally have Private Channels in Microsoft Teams, here are some of my first impressions.

👍 Private Channels are created without the Wiki tab

👉 Private Channels create a new SharePoint site collection (based upon a modern Team)

👉 A Private Channel’s site collection’s Alias (URL) is prefixed with its “parent” Team’s Alias (URL):

  • Team Name: Human Resources
  • Private Channel Name: Annual Reviews
  • https://[company].sharepoint.com/sites/HumanResources-AnnualReviews

👍 Space re removed from a Private Channel’s title when a site collection’s Alias (URL) is created:

  • Private Channel Name: Annual Reviews
  • https://[company].sharepoint.com/sites/HumanResources-AnnualReviews

👎 Private Channels’ site collections are not available to see within the ‘modern’ SharePoint Admin Center. Other site collections are listed under the Active Sites page.

💀 Deleting a Private Channel also deletes the site collections (as expected). However the site collections is not available for recovery within the SharePoint Admin Center, under the Deletes Sites page.

👉 Private Channels site collection’s logo is not inherited from the Team and cannot be updated using the Microsoft Teams App. However it can be changed using the modern SharePoint UI.

👉 A Private Channel’s site collection’s homepage is the Documents library. It does not have the Site Pages feature activated and therefore does not have a Site Pages library.