Sunday 15 September 2024

People Picker in Adaptive Cards

In this blog, we will be learning about People Picker in Adaptive Cards.

People Picker is an input control in Adaptive Card. It allows users to quickly search and select valid user accounts for peoples within the organization.

People Picker supports the following features:

  • Searches single or multiple users.
  • Selects single or multiple users.
  • Reassigns to single or multiple users.
  • Prepopulates the name of selected users.


Implementation of People Picker

People Picker in Adaptive Cards is implemented as an extension of the Input.ChoiceSet control.

Schema

The following properties are additions to the Input.ChoiceSet schema to enable People Picker experience on the Adaptive Card.

Input.ChoiceSet control

The choices.data property is supported in version 1.6; however, in my testing, it also worked for version 1.4. The JSON format data is passed into the property.

Property Type Required Description
choices.data Data.Query No Enables dynamic auto complete for different user types, by fetching results from the dataset specified.

Data.Query

Property Type Required Description
dataset String Yes The type of data that must be fetched dynamically.

dataset

The following table provides predefined values as dataset for people picker:

dataset Search Scope
graph.microsoft.com/users Search all members across the organization.
graph.microsoft.com/users?scope=currentContext Search within the members of the current conversation, such as chat or channel in which the particular card is sent.

Data Submission

We can use Action.Submit or Action.Execute to submit selected user data. The payload received is a list of Microsoft Entra IDs or the IDs provided in the static list. In People Picker, when a user is selected in the control, the Microsoft Entra ID of the user is the value sent back. The Microsoft Entra ID is a string and uniquely identifies a user in the directory.


Create Flow

1). Sign in to Power Automate

2). Open the flow, click on the Create option, and select "Instant Cloud Flow".

Enter Flow name.
Choose the flow trigger as "Manually trigger a flow".
Click on the Create button.




3). Add an action "Post adaptive card and wait for a response".
Add mandatory parameter values as shown in below image.


In this step an Adaptive Card with People Picker control will be sent to user in MS Teams chat. It will wait till the user has search & selected the user(s) and clicked on 'Save' button.

4). Add a loop "Apply to each" and set input value "Select an output from previous steps" as below

split(body('Post_adaptive_card_and_wait_for_a_response')?['data']?['peoplePickerChoiceSetControlID'],',')

Then add an action "Get user profile (V2)" and enter User (UPN) value as current item.

Here, we are retrieving the user(s) that has been selected and submitted from above step. When a user is selected in the control, the Microsoft Entra ID (Azure Active Directory) of the user is the value sent back. The value will be comma separated user ID's if multi select is enabled.
To compare, we will iterate over the values and verify if the chosen user matches the one we have received.


Repeat above step for all the four People Picker controls added in Adaptive card.

Now we will discuss how to create Adaptive Card parameter value.

5). Open Adaptive Cards Designer portal.

Select host app as "Microsoft Teams" and Target version as 1.4
Then, create the Adaptive card design according to your requirements.

Once Adaptive Card design is complete. Click on "Copy card payload" and paste it into the  Adaptive Card parameter value (Step 3)



People Picker - CARD PAYLOAD
{
    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.4",
    "id": "peoplePickerCard",
    "msteams": {
        "width": "Full"
    },
    "body": [
        {
            "type": "TextBlock",
            "size": "ExtraLarge",
            "weight": "Bolder",
            "text": "People Picker in Adaptive Cards",
            "id": "peoplePickerTitle",
            "horizontalAlignment": "Center",
            "fontType": "Default"
        },
        {
            "type": "Container",
            "items": [
                {
                    "type": "TextBlock",
                    "text": "People Picker with organization search - 
                             Default",
                    "wrap": true,
                    "id": "peoplePickerDefault",
                    "weight": "Bolder",
                    "spacing": "None"
                },
                {
                    "type": "ColumnSet",
                    "columns": [
                        {
                            "type": "Column",
                            "width": "stretch",
                            "items": [
                                {
                                    "type": "TextBlock",
                                    "text": "Single select",
                                    "wrap": true,
                                    "id": "textBlockSingleSelectDefault",
                                    "fontType": "Monospace"
                                },
                                {
                                    "type": "Input.ChoiceSet",
                                    "choices.data": {
                                        "type": "Data.Query",
                                        "dataset": "graph.microsoft.com/users"
                                    },
                                    "id": "peoplePickerControlSingleSelectDefault",
                                    "placeholder": "Search user"
                                }
                            ]
                        },
                        {
                            "type": "Column",
                            "width": "stretch",
                            "items": [
                                {
                                    "type": "TextBlock",
                                    "text": "Multi select",
                                    "wrap": true,
                                    "id": "textBlockMultiSelectDefault",
                                    "fontType": "Monospace"
                                },
                                {
                                    "type": "Input.ChoiceSet",
                                    "choices.data": {
                                        "type": "Data.Query",
                                        "dataset": "graph.microsoft.com/users"
                                    },
                                    "id": "peoplePickerControlMultiSelectDefault",
                                    "isMultiSelect": true,
                                    "placeholder": "Search users"
                                }
                            ]
                        }
                    ]
                }
            ],
            "backgroundImage": {
                "url": "data:image/gif;base64,
                R0lGODlhCAABAIABAOrbyAacDywAAAAACAABAAACA4RvBQA7",
                "fillMode": "Repeat"
            },
            "spacing": "ExtraLarge",
            "separator": true
        },
        {
            "type": "Container",
            "items": [
                {
                    "type": "TextBlock",
                    "text": "People Picker with organization search - 
                             User Preselection",
                    "wrap": true,
                    "id": "peoplePickerPreselection",
                    "spacing": "ExtraLarge",
                    "weight": "Bolder"
                },
                {
                    "type": "ColumnSet",
                    "columns": [
                        {
                            "type": "Column",
                            "width": "stretch",
                            "items": [
                                {
                                    "type": "TextBlock",
                                    "text": "Single select",
                                    "wrap": true,
                                    "id": "textBlockSingleSelectPreselection",
                                    "fontType": "Monospace"
                                },
                                {
                                    "type": "Input.ChoiceSet",
                                    "choices.data": {
                                        "type": "Data.Query",
                                        "dataset": "graph.microsoft.com/users"
                                    },
                                    "id": "peoplePickerControlSingleSelectPreselection",
                                    "placeholder": "Search user",
                                    "value": "b8e32ece-6d19-488e-96cf-7703c5xxxxxx"
                                }
                            ]
                        },
                        {
                            "type": "Column",
                            "width": "stretch",
                            "items": [
                                {
                                    "type": "TextBlock",
                                    "text": "Multi select",
                                    "wrap": true,
                                    "id": "textBlockMultiSelectPreselection",
                                    "fontType": "Monospace"
                                },
                                {
                                    "type": "Input.ChoiceSet",
                                    "choices.data": {
                                        "type": "Data.Query",
                                        "dataset": "graph.microsoft.com/users"
                                    },
                                    "id": "peoplePickerControlMultiSelectPreselection",
                                    "isMultiSelect": true,
                                    "placeholder": "Search users",
                                    "value": "b8e32ece-6d19-488e-96cf-7703c5xxxxxx,
                                              e59ec47a-1e87-4ecf-983c-6b7efdxxxxxx"
                                }
                            ]
                        }
                    ]
                }
            ],
            "spacing": "Padding",
            "backgroundImage": {
                "url": "data:image/gif;base64,
                R0lGODlhCAABAIABAOrbyAacDywAAAAACAABAAACA4RvBQA7"
            }
        }
    ],
    "actions": [
        {
            "type": "Action.Submit",
            "title": "Save",
            "iconUrl": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg
            AAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAhhJREFUOE9jZK
            AyYKSyeQwoBprMuO3/n4FBg+/XG9cYAyElXoYffDALX//jfoNs+ZpLr5
            98ZxVIOZGp+QBZHG6gybTbfgxMDBtBkmK/XjD0eEkxPHjyBK7WzMAAxT
            Nxiy4xvGSTfMD6/7cjsqEIA2fermf4z9AAM7DVVZTh2LlzcEPCvb0xDH
            zFJsHwn4ERxVCEgdNvNzAwMtSDdDF/eMSwLEaT4eylSwx//v1lEODlYz
            DT14Mb+OvPP4aA2ecY/gnKQcT+MzSeyVQFOwargd/fPmUwleZkcNcQYW
            BhZkJx2Z+//xh2Xn/NcObZDwYOYWncBhpNvDqPiZ0tEWzhvz8Mf75/Yf
            j/7x/WRMDIxMzAwsnDAKJB4N/PX/PP5WsnobhQr//8ATZOHntyktGv71
            8OXio0dKCvgRI8zAy8bNjT/edf/xlefPmLiCRCLsw14WXwVuHE6/stt7
            8zTDn7GayGoJc3h4ky/P31i+Hjp09YDeXn42NgZmNj8F31mjgDd0SIMf
            z+/Yfh67dvWA3k5uJiYGVlYfBY8Yp4Az9/+crw7PkLrAZKSUow8PJw4z
            dQv/fMelZu/gCQCSAXEgNgLvz59eP6y8UmQSjJRrd5TwAjB+96ZlZ2hk
            YbbmLMY6g/8pXh7+8fDH9/fPK/Wuu2CcVAEEejcacvw///FolanEQl8P
            nXvh9kYGA8fqPBfQvMBbQtYInyJwFFAGUS8BXW+cfxAAAAAElFTkSuQmCC",
            "id": "peoplePickerSubmit"
        }
    ],
    "backgroundImage": {
        "url": "data:image/gif;base64,
        R0lGODlhCAABAIABAPjw5QacDywAAAAACAABAAACA4RvBQA7",
        "fillMode": "Repeat"
    }
}


6). Complete flow with all the actions will look like below.



Now it's time to test the flow. Manually run the flow and wait for sometime.

People Picker in Adaptive Card output for Teams desktop application.


People Picker in Adaptive Card output for Teams web application.


Select the user(s) and click Save button.



Refer Adaptive Card blog series:
Adaptive Card: Power Automate send welcome message when new team member added
Adaptive Card: Power Automate send birthday greetings to team members
People Picker in Adaptive Cards
Adaptive Card: Send Form using Adaptive card in MS Teams to group members


I hope this will help all of you! 🧲
Feel free to provide feedback.


🚀 "Happy Coding" 🚀

Wednesday 28 August 2024

Adaptive Card: Power Automate send birthday greetings to team members

In this blog, we will be learning about Adaptive Cards and how to send a birthday greetings automatically to Team's channel to team members.

Create Flow

1). Sign in to Power Automate

2). Open the flow, click on the Create option, and select "Scheduled Cloud Flow".

Enter Flow name.
Set the flow recurrence interval as daily.
Click on the Create button.


3). Initialize variable of Array type.

4). Add an action "List group members" and enter team name from the dropdown in Group Id parameter. Its used to get all the members details present in the teams in an array.


5). Add "Apply to each" loop and enter previous step output as input value.

6). Add an action "Get user profile (V2)" and enter User (UPN) value as "User Principal Name" dynamic content from step 4.

7). Append the array variable (defined in step 3) value in JSON format for "Display Name", "User Principal Name", "Birthday".

{
  "name": "@{outputs('Get_user_profile_(V2)')?['body/displayName']}",
  "email": "@{outputs('Get_user_profile_(V2)')?['body/userPrincipalName']}",
  "birthday": "@{outputs('Get_user_profile_(V2)')?['body/birthday']}"
}


8). Add an action "Filter Array" and enter array variable in From parameter value.

@equals(formatDateTime(convertFromUtc(item()['birthday'], 'India Standard Time'), 'MM-dd'), formatDateTime(convertFromUtc(utcNow(), 'India Standard Time'), 'MM-dd'))


9). Add "Apply to each" loop and enter previous step output as input value.

10). Add an action "Compose" and add Adaptive Card payload in the inputs parameter (refer step 12).

11). Now, add an action "Post card in a chat or channel" and "Send an email (V2)".
Add mandatory parameter values as shown in below image.


12). Open Adaptive Cards Designer portal and create the Adaptive card design according to your requirements.

Once Adaptive Card design is complete. Click on "Copy card payload" and paste it into the  Adaptive Card parameter value (Step 11)


Then add dynamic values for the user display name and user photo (yellow highlighted).

Happy Birthday - CARD PAYLOAD
{
    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.4",
    "body": [
        {
            "type": "TextBlock",
            "text": "🎂 Happy Birthday 🎂",
            "wrap": true,
            "id": "happyBirthdayCard-Title",
            "horizontalAlignment": "Center",
            "size": "ExtraLarge",
            "weight": "Bolder",
            "fontType": "Monospace"
        },
        {
            "type": "ColumnSet",
            "columns": [
                {
                    "type": "Column",
                    "width": "stretch",
                    "items": [
                        {
                            "type": "Image",
                            "id": "happyBirthdayCard-Image",
                            "url": "https://cdn0.iconfinder.com/data/icons/
                                    birthday-sticker/100/14_happy_birthday_
                                    balloon_event_celebration-1024.png",
                            "separator": true,
                            "horizontalAlignment": "Center"
                        }
                    ]
                },
                {
                    "type": "Column",
                    "width": "stretch",
                    "items": [
                        {
                            "type": "TextBlock",
                            "text": "Hi Vikas Bansal,",
                            "wrap": true,
                            "id": "happyBirthdayCard-MailHeader",
                            "weight": "Bolder",
                            "size": "Medium"
                        },
                        {
                            "type": "TextBlock",
                            "text": "We extend our warmest wishes for a
                                     wonderful birthday and a year filled
                                     with cherished memories. Best regards
                                     from all of us.",
                            "wrap": true,
                            "id": "happyBirthdayCard-MailBody"
                        },
                        {
                            "type": "TextBlock",
                            "text": "Team HR",
                            "wrap": true,
                            "id": "happyBirthdayCard-MailFooter"
                        }
                    ],
                    "id": "happyBirthdayCard-Column",
                    "verticalContentAlignment": "Center"
                }
            ],
            "separator": true
        }
    ],
    "id": "happyBirthdayCard"
}


13). Complete flow with all the actions will look like below.



Now it's time to test the flow. Manually run the flow and wait for sometime.

Adaptive Card output for Teams desktop application.



Adaptive Card output for Teams web application.



Adaptive Card output for Outlook web application.



Refer Adaptive Card blog series:
Adaptive Card: Power Automate send welcome message when new team member added
Adaptive Card: Power Automate send birthday greetings to team members
People Picker in Adaptive Cards
Adaptive Card: Send Form using Adaptive card in MS Teams to group members


I hope this will help all of you! 🧲
Feel free to provide feedback.


🚀 "Happy Coding" 🚀

Friday 19 July 2024

Adaptive Card: Power Automate send welcome message when new team member added

In this blog, we will be learning about Adaptive Cards and how to send a welcome message automatically to Team's channel when a new member is added to the team.

What is Adaptive Card?

Adaptive cards are a platform-agnostic method of sharing and displaying blocks of information without the complexity of customizing CSS or HTML to render them. Adaptive Cards are authored in JSON format enabling developers to exchange UI content in a common and consistent way with cloud apps and services integrations.

Create Flow

1). Sign in to Power Automate

2). Open the flow, click on the Create option, and select "Automated Cloud Flow".

Enter Flow name.
Choose the flow trigger as "When a new team member is added".
Click on the Create button.


3). Enter the team name in trigger action.

4). Initialize variable of string type.


5). Add an action "Get user profile (V2)" and enter User (UPN) value as trigger output User ID.

6). Add an action "Get user photo metadata" and enter User (UPN) value as trigger output User ID.


7). Add a condition to check if user "Has photo" or not.

a) If Yes, add an action "Get user photo (V2)" and enter User (UPN) value as trigger output User ID. Set variable value as base64 encoded image content (received from above).

concat('data:image/png;base64,',body('Get_user_photo_(V2)')?['$content'])

b) If No, set variable value as default/fallback image absolute hyperlink.


8). Now, add an action "Post card in a chat or channel".
Add mandatory parameter values as shown in below image.


Now we will discuss how to create Adaptive Card parameter value.

9). Open Adaptive Cards Designer portal.

Select host app as "Microsoft Teams" and Target version as 1.4


⊛ Note

  • Adaptive Card payload size in Microsoft Teams should be less than 28KB. This limit applies to the entire card, including all its elements and actions.
  • The latest Target version didn't work, but version 1.4 worked in my testing.
  • Image element:
    • URL's must start with https and and ends with file extension like JPEG, PNG, GIF.
    • URL can be an absolute hyperlink to image or base64 encoded file contents.
    • Emoji's can render differently based on the device's OS (Windows, Android, iOS) and even vary in web browsers.


10). Click on "New card" and select Blank Card template. However you can use existing available templates as well and modify them as per your requirements.


11). Select the required elements from the Card Element left pane. Then drag and drop onto the Card Design area.


12). Set the Card element properties. Currently, we will set the static details and later on add dynamic data from flow itself.


13). Once Adaptive Card design is complete. Click on "Copy card payload" and paste it into the  Adaptive Card parameter value (Step 8)

Then add dynamic values for the user display name and user photo (yellow highlighted).

Welcome Message - CARD PAYLOAD
{
    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.4",
    "body": [
        {
            "type": "TextBlock",
            "text": "Greetings and welcome to the team!",
            "wrap": true,
            "id": "welcomeCardTitle",
            "horizontalAlignment": "Center",
            "fontType": "Monospace",
            "size": "Large",
            "weight": "Bolder",
            "color": "Accent"
        },
        {
            "type": "Image",
            "url": "https://cdn1.iconfinder.com/data/icons/
                    user-pictures/101/malecostume-64.png",
            "altText": "Vikas Bansal",
            "horizontalAlignment": "Center",
            "id": "welcomeCardProfileImage",
            "separator": true,
            "style": "Person",
            "size": "Medium"
        },
        {
            "type": "TextBlock",
            "text": "Vikas Bansal",
            "wrap": true,
            "fontType": "Default",
            "size": "ExtraLarge",
            "weight": "Bolder",
            "color": "Dark",
            "horizontalAlignment": "Center",
            "id": "welcomeCardDisplayName"
        },
        {
            "type": "TextBlock",
            "text": "Welcome aboard to our team, it's truly incredible to
                     have a fresh and talented new member on board!
                     Through our collaboration, we are poised to elevate
                     the company to new heights. 🚀🚀",
            "wrap": true,
            "id": "welcomeCardDescription",
            "size": "Small",
            "weight": "Default",
            "separator": true
        },
        {
            "type": "Image",
            "id": "welcomeCardDescriptionImage",
            "horizontalAlignment": "Center",
            "url": "https://cdn1.iconfinder.com/data/icons/
                    welcome-greeting-illustration/3000/Welcome-03-256.png"
        }
    ],
    "id": "welcomeCard"
}


14). Complete flow with all the actions will look like below.



Now its time to test the flow. Add an user in the Teams as provided in the flow and wait for sometime.

Adaptive Card output for Teams desktop application.



Adaptive Card output for Teams web application.





Refer Adaptive Card blog series:


I hope this will help all of you! 🧲
Feel free to provide feedback.


🚀 "Happy Coding" 🚀

Wednesday 10 July 2024

Microsoft Important Links 🔗 🔗

In this blog, I will share some important Microsoft links.

aka.ms/ge

aka.ms/azad

aka.ms/admin

aka.ms/ppac

aka.ms/sspr

o365.rocks or https://accessorange.com/tenant_check/tenant-check.php

aka.ms/spfx

aka.ms/portal or aka.ms/azure

aka.ms/flow

aka.ms/aaddev

aka.ms/login

aka.ms/quickstart

aka.ms/m365pnp or aka.ms/pnp


I hope this will help all of you! 🧲
Feel free to provide feedback.


🚀 "Happy Coding" 🚀

Monday 10 June 2024

Microsoft Graph API - Open Type Extension

In this blog, we will be learning about Microsoft Graph Extensibility - Open Type Extension.


What are Microsoft Graph Extensions?

Microsoft Graph provides a single API endpoint to access rich people-centric data and insights through resources such as user and message. You can also extend Microsoft Graph by adding custom properties to resource instances without requiring an external data store.

Microsoft Graph offers four types of extensions for adding custom data.

  • Extension attributes
  • Directory (Microsoft Entra ID) extensions
  • Schema extensions
  • Open extensions


Open Extensions

Here we will be discussing Open extensions.

  • It allows us to add untyped properties to resources in Graph.
  • Each extension has a key/value property.
  • The name of the extensions should include a reverse domain name system (DNS) format that is dependent on our own domain; for example, the DNS name com.mydomain.UserInfo
  • Can be added, updated, and deleted.

⊛ Note

Do not use extensions to store sensitive personally identifiable information, such as account credentials, government identification numbers, cardholder data, financial account data, healthcare information, or sensitive background information.


The following resources support open extension:
Resource Status Permission
Administrative unit Preview Only Directory.AccessAsUser.All
Calendar event GA Calendars.ReadWrite
Group calendar event GA Group.ReadWrite.All
Group conversation thread post GA Group.ReadWrite.All
Device GA Device.ReadWrite.All
Group GA Group.ReadWrite.All
Message GA Mail.ReadWrite
Organization GA Directory.AccessAsUser.All
Personal contact GA Contacts.ReadWrite
User GA Directory.AccessAsUser.All

We will be working around User resource in the Graph

Open Microsoft Graph Explorer - aka.ms/ge

The first thing is to provide permissions (refer to the above table) to use the Microsoft Graph API endpoint.



Get an Extension

Enter the below table details and press the 'Run query' button. We will get OK-200 status and blank/empty array as we currently don't have any extensions available. (we'll get extensions again further in the blog).

Verb GET
URL https://graph.microsoft.com/v1.0/me?
$select=id,displayName,mail,mobilePhone&$expand=extensions



Create an Extension

Enter the below table details and press the 'Run query' button. The new open extension will be created, and we will get Created-201 status.

Verb POST
URL https://graph.microsoft.com/v1.0/me/extensions
Body
{
  "@odata.type": "microsoft.graph.openTypeExtension",
  "extensionName": "com.vikasbansal.userSettings",
  "costCenter": "Engineering-007",
  "myFavouriteApps": [
    {
      "name": "SSP",
      "description": "Self Service Portal",
      "Url": "https://aks.ms/sspr",
      "iconName": "EmployeeSelfService"
    },
    {
      "name": "Open AI",
      "description": "Open Artificial Intelligence",
      "Url": "https://openai.com",
      "iconName": "GiftboxOpen"
    },
    {
      "name": "My IT Support",
      "description": "Access IT updated and support materials",
      "Url": "https://www.myitsupport.com",
      "iconName": "AnalyticsView"
    },
    {
      "name": "Policies Hub",
      "description": "Get latest updates on company policies",
      "Url": "https://www.policyhub.com",
      "iconName": "EntitlementPolicy"
    },
    {
      "name": "Office 365",
      "description": "My Office 365",
      "Url": "https://office.com",
      "iconName": "OfficeLogo"
    }
  ]
}





Update an Extension

Enter the below table details and press the 'Run query' button. The open extension value will be updated, and we will get a No Content-204 status.
{Extension-Id} is the name of the extension previously created.

Verb PATCH
URL https://graph.microsoft.com/v1.0/me/extensions/{extension-id}
https://graph.microsoft.com/v1.0/me/extensions/com.vikasbansal.userSettings
Body
{
  "@odata.type": "microsoft.graph.openTypeExtension",
  "extensionName": "com.vikasbansal.userSettings",
  "costCenter": "Engineering-005",
  "myFavouriteApps": [
    {
      "name": "ESP",
      "description": "Employee Service Portal",
      "Url": "https://aks.ms/sspr",
      "iconName": "EmployeeSelfService"
    },
    {
      "name": "Open AI",
      "description": "Open Artificial Intelligence",
      "Url": "https://openai.com",
      "iconName": "GiftboxOpen"
    },
    {
      "name": "My IT Support",
      "description": "Access IT updated and support materials",
      "Url": "https://www.myitsupport.com",
      "iconName": "AnalyticsView"
    },
    {
      "name": "Policies Hub",
      "description": "Get latest updates on company policies",
      "Url": "https://www.policyhub.com",
      "iconName": "EntitlementPolicy"
    },
    {
      "name": "Office 365",
      "description": "My Office 365",
      "Url": "https://office.com",
      "iconName": "OfficeLogo"
    }
  ]
}





Again, enter the Get extension table details and press the 'Run query' button. We will get OK-200 status, and the extensions array will contain available extension details against the user resource in Graph.



Delete an Extension

Enter the below table details and press the 'Run query' button. The open extension will be deleted, and we will get a No Content-204 status.
{Extension-Id} is the name of the extension previously created or updated.

Open Extension once deleted, cannot be restored but can be created again with the same name.

Verb DELETE
URL https://graph.microsoft.com/v1.0/me/extensions/{extension-id}
https://graph.microsoft.com/v1.0/me/extensions/com.vikasbansal.userSettings




Open Extensions: Limitations and Useful Information

  • Resources cannot be filtered based on open extensions.
  • Each open extension can have up to 2 KB of data (including the extension definition).
  • An application can add up to two open extensions per resource instance.
  • There is no transaction context while working on extensions.


I hope this will help all of you! 🧲
Feel free to provide feedback.


🚀 "Happy Coding" 🚀

Wednesday 20 December 2023

SharePoint site theme: Add a custom theme using PowerShell

In this blog, we will be learning how to create a custom theme for SharePoint Online.

Now SharePoint has a Site theming feature for applying custom styles and colors to the site. There are six light and two dark themes available by default. This feature provides the ability to define custom themes and make them available to site owners. Creating a custom theme in SharePoint is a quick and easy way to give your site a unique look and feel.

Currently, no theme is available under the "From your organization" option.


The steps to add a custom theme to SharePoint Online.

Step 1: Create a new color theme in SharePoint Online.

Themes are defined in a JSON schema that stores color settings and related metadata for each theme. Create a new custom theme for SharePoint Online using Microsoft Fluent UI Theme Designer, an online tool. Customize the theme as per your needs and click on the Export theme button. Copy and save the PowerShell output for later use.

Light Theme sample:


Dark Theme sample:


Step 2: Add a custom theme to SharePoint Online using PowerShell

First, connect to the SPO admin site using the Connect-SPOService cmdlet. The custom theme can be added to the SharePoint online tenant using the Add-SPOTheme cmdlet. This cmdlet creates a new theme or updates an existing theme. The color palette settings can be passed as either a hash table or a dictionary.

Execute the command for the light theme.



Now go to Site Settings, gear icon (⚙️) > Change the look > Theme and you'll find the newly added color theme listed under "From your organization".


Execute the same command for the dark theme.


Again, go to Site Settings gear icon (⚙️) > Change the look > Theme and you'll find the new added color theme listed under "From your organization".


When you choose a theme, color settings are instantly applied to the site so that you can see what the selected theme will look like. Select the desired theme, click Save to save your selection, or choose Cancel to revert to your current theme.

Our "Maroon - Light theme" output looks like




Our "Orange - Dark theme" output looks like




Update SP Theme
To update an existing theme (to modify some of its color settings, for example), add the -Overwrite flag to the Add-SPOTheme cmdlet.


I hope this will help all of you! 🧲
Feel free to provide feedback.


🚀 "Happy Coding" 🚀