Power Automate: Embed an image in an email


It sounds easy but believe me it is not so easy that it sounds like. There is no direct way that you can embed an image when you are drafting “Send Email” action even when you are planning to use HTML code in email body. There is a way to add a Image html tag but question is what will be the URL/SRC for same. Suppose you want to place image url which is exposed on internet, accessibility set to public, in that case you saved your time. Just use the URL in image tag and it will work.

So just wanted to mention one more important thing here. Email can we viewed by multiple means: MS Outlook or from Browser. The behavior in both the cases will be different. I have observed the behavior that sometimes when email is opened using browser it renders images perfectly but when same email was opened using MS Outlook app, images shows just cross marks. May be due to the reason the images can easily be accessible using browser but Outlook it may require some extra steps.

After spending two or three days, trying different options, I finally got a solution which works in all cases.

Problem:

Using Microsoft Flow, trigger sending of an email with an embedded image.

  • The image will be stored in a SharePoint Library/One drive
  • We will assume you have already created connects to:
    • Office 365 Outlook
    • SharePoint/Outlook

Solution:

  1. Create a new Flow:
    1. Select: +New Instant—from blank
    2. Click: Manually trigger a flow
  2. Add the 1st actions:
    1. Search for SharePoint > Get file content using path
    2. Select the action
    3. Site Address: either select or ‘enter custom value’
    4. File Path: enter the path from the site collection (e.g. ‘/Style%20Library/DemoFile/EmailCompanyLogo.jpg’)
  3. Add the 2nd actions:
    1. Search for Variables > Initialize variable
    2. Select the action
    3. Name: Enter ImageTag
    4. Type: Select String
    5. Value: This is the trick bit!*
      1. Enter: <img src=”data:image/jpeg;base64,” alt=”CompanyLogo” />
      2. Next click between ‘64,‘ and ‘” alt
      3. Add dynamic content
      4. Select: Expression fx
      5. Enter .$content
      6. Placing you cursor before the .$content click: Dynamic content
      7. Locate and select File Content
      8. Click OK
  4. Add the 3rd and last actions:
    1. Search for Office 365 Outlook > Send an email
    2. Select the action
    3. To: enter your email address
    4. Subject: Microsoft Flow: How to embed an image in an email
    5. Body: <p>This is my test email, you should see an image below</p><p></p>
    6. Click between the last <p></p> tags
    7. Click: Add dynamic content
    8. Locate and select the ImageTag variable
    9. Is HTML: Select Yes
  5. Save the Flow

*Here is the full code/expression:

<img src="data:image/jpeg;base64,@{body('Get_file_content_using_path')['$content']}" alt="My Image" />

Note: The other way to implement the same requirement is to attach as attachment to the email action. Provide file content as Attachment Content and image will be rendered as usual.

Please feel free to hit like button in case you find the content of this bog helpful.

Happy PowerAutomating !!

Disable Page Comments: SP Online


Requirement: SharePoint Online has awesome feature at every modern page called “Comment Section” which usually displayed at bottom of the page for better collaboration. My client has requested that they do not want to provide this option to their users. So requirement Disable page comments in SharePoint Online Modern Sites and Communication sites.

Solutions

  • Option 1: Disable Comments at the tenant level

Page comments can be turned-off at tenant level by the below settings:

  1. Navigate to SharePoint Online Admin Center: https://yourdomain-admin.sharepoint.com 
  2. Click on Settings from left navigation
  3. On the Settings page, Select “Disable Comments on Site Pages.”
  4. Click OK to save your changes.

Wait for a while, the comments section disabled from all pages in the tenant. You can disable comments on modern pages at tenant level using PowerShell as well:

$AdminCenterURL="https://crescent-admin.sharepoint.com" 
#Connect to SharePoint Online
Connect-SPOService -Url $AdminCenterURL -Credential (Get-Credential) 
#Disable Comments on Site Pages at Tenant Level
Set-SPOTenant -CommentsOnSitePagesDisabled $True
  • Option 2: Disable Comments at the Page Level 

Comments can be disabled at page level. Here is how:

  • Navigate to the SharePoint Online Site page >>  Edit the page.
  • Turn off the comments by toggle the switch from ON to OFF position and Publish the page.

This disables comments section in the particular page.

  • Option 3: Disable Comments in SharePoint Online Pages using PowerShell

This PowerShell script disables the page comments for given site.

#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
  
#Config Parameters
$SiteURL="https://crescent.sharepoint.com/sites/GroupIT"
  
Try {
    #Get Credentials to connect
    $Cred= Get-Credential
  
    #Setup the context
    $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
    $Ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
   
    #Get the Web
    $Web = $ctx.Web
    $Ctx.Load($Web)
    $Ctx.ExecuteQuery()
 
    #Disable Comments in Site Pages
    $Web.CommentsOnSitePagesDisabled = $True
    $Web.Update()
    $Ctx.ExecuteQuery()
    Write-host -f Green "Page Comments has been disabled Successfully!"
}
Catch {
    write-host -f Red "Error:" $_.Exception.Message
}

Please note, disabling comments doesn’t delete existing comments on pages. It just hides them. Turning ON comments brings the comments back!

PnP PowerShell to Disable Comments on All Pages in a Library

#Parameter
$SiteURL= "https://crescent.sharepoint.com/sites/marketing/2018"
$LibraryName = "SitePages"
 
#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -Credentials (Get-Credential)
 
#Get all Pages from the Library
$Pages = Get-PnPListItem -List $LibraryName
 
#Loop through each Page
ForEach($Page in $Pages)
{
    #Disable Comments
    Write-host "Disabling Commnets on page:"$Page["FileLeafRef"]
    Set-PnPClientSidePage -Identity $Page["FileLeafRef"] -CommentsEnabled:$False
}

Do not forget to hit like in case you find this blog stuff helpful. Happy SharePointing !!!!!

Office 365: Configure CDN at Tenant


If you have developed a SPFx solutions, it is important to configure this setting at your tenant level. We have recently faced an issue where external user/guest users are not able to see the webparts because CDN is not configured at tenant. For developers, to enable hosting your SPFx solution from SharePoint, you need to have “includeClientSideAssets” as “true” in the package-solution.json file. This configuration is also typically ignored when building debug builds (bundle without –ship).

Any of the document libraries in the SharePoint Online tenant can be promoted as a CDN, which will help to serve the JS files for SPFx client web parts hosted in SharePoint. This CDN location, being public, can be accessed easily. To configure the CDN in Office 365 follow the below steps,

Prepare your PowerShell environment

Connect to Office 365 tenant using PS

  • Connect to SharePoint Online tenant using below cmdlet
    • Connect-SPOService -Url https://[tenant]-admin.sharepoint.com    
    • Replace [tenant] with your actual tenant name

Examine existing configuration of Office 365 tenant

  • Run below set of commands to review the existing Office 365 public CDN settings on your tenant. This command will return the status of CDN. True if CDN is enabled, false otherwise. 
    • Get-SPOTenantCdnEnabled -CdnType Public    
SharePoint
  • Next, in order to see the CDN Origins which are made public execute this comment
    • Get-SPOTenantCdnOrigins -CdnType Public
    • This command will return the location of already configured CDN origins. The URLs are relative. In the first instance, it will not return any values as CDN is not yet set up.
SharePoint
  • Now, to view the policy settings for CDN  Run below command to enable the CDN
    • Get-SPOTenantCdnPolicies -CdnType Public
SharePoint

Enable CDN, Origins and Policies for connected tenant

Now in this step we will actually going to modify the tenant configuration for enabling CDN. Execute below command in order to enable CDN:

Set-SPOTenantCdnEnabled -CdnType Public  

SharePoint

 After enabling the CDN, */CLIENTSIDEASSETS origin is by default added as a valid origin. By default allowed file extensions are: CSS, EOT, GIF, ICO, JPEG, JPG, JS, MAP, PNG, SVG, TTF, and WOFF. The configuration takes up to 15 to 20 minutes. To check the current status of CDN endpoints, run below command

Get-SPOTenantCdnOrigins -CdnType Public  

SharePoint

 The origin will be listed without (configuration pending) status when it is ready. Please be patient for 15 to 20 minutes until it is ready. Once CDN origin is ready, the output will be as below. 

SharePoint

Please do not forget to hit like in case you like the stuff I posted. Cheers !

Trigger a SP workflow on a timer basis: Information management policies


How to trigger a workflow on a timer basis: Information management policies

Steps:

Configure settings on Document Library:

  1. Open SharePoint Site and go to Library Settings of document library where you want to configure Information Management Policies.
  2. On Library Settings Page click on the Content Type for which you want to configure Information Management Policies. E.g.:
  3. On Content type settings page click on “Information management policy settings”
  4. On Edit Policy Page, click on “Enable Retention” checkbox so the Add a retention stage link will be visible. Click on Add a retention stage link.
  5. On Stage properties dialog specify following input for time period:
    1. Select “Created” field in the columns dropdown.
    2. And specify 0 in the textbox and select days in the dropdown.
  6. On Stage properties dialog select “Start a workflow” in the action dropdown and in start this workflow dropdown select the workflow that you want to start and click on OK button in the dialog.
  7. Click on OK button on Edit Policy Page.

Change the schedule of Information management policies timer jobs

  1. Open SharePoint Central Administration Site and go to Monitoring -> Review job definitions.
  2. On Job Definitions Page, look for the “Information management policy” timer job for the web application where you have configured Information management policy on document library.
  3. On Edit Timer Job Page change the schedule to run every 1 min as follows:
    • Select Minutes radio button.
    • And specify 1 in the textbox.
    • Click on OK button.
  4. Again go to Job Definitions Page, look for the “Expiration policy” timer job for the web application where you have configured Information management policy on document library.
    • Select Minutes radio button.
    • And specify 2 in the textbox.
    • Click on OK button.
  5. Now workflow will be triggered approximately 3-5 minutes after a new document or form is created in your library using the content type for which you configured Information management policy.

Notes:

If you do any changes in workflow publish the workflow after configuring the information management policies then you will need to update the workflow in Information management policies settings as follows:

  1. Go to Information management policies settings of content type as mentioned in above steps(1 to 3)
    1. Click on “Edit” option for the retention policy.
    2. If you see the workflow then it must be showing Previous version in the Start this workflow dropdown as shown in the below screen shot.
    3. So change the workflow in the Start this workflow dropdown to the actual workflow that you want to run and click on OK button.
    4. Click on OK button on Edit Policy page.

Happy SharePointing !!

Get Yammer Group Details using PowerShell


Hello Guys,

While working with cloud platform you might face any random requirement from your clients. I was asked if it is possible to work with yammer using Powershell commands. My first thought was it should not be easy to do but with very first internet search, I found REST APIs which are exposed by yammer and can be utilized anywhere with developer token. I am sharing my first very basic yammer powershell command in this blog, I will explain how to get all of the Yammer groups using PowerShell.

Step 1: Register an app

Navigate to https://www.yammer.com/client_applications and register an app. Fill out mandatory details on the form and click on submit.


Once the app is registered, you can view details of newly created app under list of applications.

Step 2: Grab developer access token

Once the app is registered, navigate to Basic information tab and find out a link “Generate a developer token for this application” to generate a developer token.


Step 3: Create PS script file with commands

Copy the below script and paste it in a notepad. Save the file as AllGroups.ps1.

# Input Parameters  
$developerToken = "12240-*****PR2NWpZVtnbXYw"  
$uri="https://www.yammer.com/api/v1/groups.json"  
$headers = @{ Authorization=("Bearer " + $developerToken) }  
  
# Invoke Web Request  
$webRequest = Invoke-WebRequest –Uri $uri –Method Get -Headers $headers  
  
# Check whether the status code is 200  
if ($webRequest.StatusCode -eq 200) {  
  
    # Converts a JSON-formatted string to a custom object or a hash table.   
    $results = $webRequest.Content | ConvertFrom-Json  
  
    write-host -ForegroundColor Magenta "Groups Count: " $results.length  
  
    # Loop through all the groups  
    $results | ForEach-Object {  
        $group = $_   
        # Display the group name and members count  
        Write-Host -ForegroundColor Green "Group Name: " $group.full_name " - Members: " $group.stats.members  
    }  
}  
else {  
    Write-Host -ForegroundColor Yellow "An error has occurred: " + $webRequest.StatusCode + " Description " + $webRequest.Status  
}  

Open PowerShell window and run the following command.

  1. >cd “<folderlocation>”  

folderlocation – YammerGroups.ps1 file location.

Run the following command.

  1. >.\YammerGroups.ps1  

So here is the list of groups that it returns:


Hope this blog helped you ! Do not forget to like and comment. Happy SharePointing !

Search Display Template: Show manager display name


In this post, I will explain how you can display the any user manager’s information in search display template. I assume here that you already have search configured on your SharePoint environment and basic knowledge of managed properties and search display template.

SharePoint introduced a technique for presenting search results: Display Templates during its 2013 release. If you have worked in previous versions of SharePoint and had to modify the look and feel of Search Results you know how cumbersome it is. After SP 2013 this rendering techniques have several distinct advantages.

  • Display templates are HTML and JavaScript rather than XSL
  • Display templates are configured for the Site and Site Collection rather than for a Web part
  • Display templates are applied with rules and logic
  • Display templates are applied to individual result items, not the entire result set
  • Display Templates are used for Results of all kinds, search results, content by search results, and refiners

If we talk about out-of-box template, it display search results like this:

Requirement:

Till this point all looks fine but what if you don’t like this version of format to show user details or may be your end user asked you to add some more information in this details like manger name or more. Definitely you require to do some custom code here. But question come where can we make change to make this happen.

Solution:

SharePoint display template by default gives you manager’s account name. I can easily be find out by debugging under developer’s tools(F12 of browser). Here are the steps:

  1. Navigate to Search result page where page is returning any results in terms of people.(/Pages/peopleresults.aspx?k=)
  2. Now press F12 of the browser, i recommend to use chrome for this purpose since it is very easy to locate resources in chrome.
  3. Under developer tools screen click on Sources tab. This will list down folders on left. Under _catalog folder expand /masterpage/display%20templates/search click on file “item_person.js”
  4. Now this is the key file which is used by sharepoint search page to render details of any person.
  5. Place a debugger and check out all the values that are out-of-box available. Here you will notice that for manager there is account name present. “ctx.CurrentItem.Manager
  6. It is very easy to locate what we are looking for. But friend no, life is not so easy in SP world, real challenge begins when you came to know that this field does not have name of manager. It have account name.

So Looks like you are on the right track by getting the manager accountID which isn’t useful to users in a display template. You can use this to get the rest of the profile information. The follow steps should get you going:

  1. Create a new “var” at the top of the template: var currentManager = ctx.CurrentItem.Manager so that you can call the variable later.
  2. At the bottom of the template add the function in this article. https://msdn.microsoft.com/en-us/library/office/jj920104.aspx where you can call multiple profile properties (its the second last JavaScript code example in the article)
  3. Update targetUser to targetUser = currentManager so we can get their profile info.
  4. The script will give you the PreferredName and Department, add any additional info that you need.
  5. Depending where exactly you want this information display, go to the area in the template that you want to show the manager’s name and put the following <div id=”ManagerValue”></div>
  6. go back to the onRequestSuccess fuction that is called if the call is successful and get rid of everything inside the function and enter the follow. $get(“ManagerValue”).innerHTML = personProperties.get_displayName(); you can also add addition <div> tags with additional information about the manager and add additional steps to the success function to show additional profile data about the manager. keep in mind you read the array from 0 up.. in the article the second profile data was the department, so you would add a div tag like <div id=”managerDept”></div> and add a success function step of document.getElementById(‘managerDept’) = userProfileProperties[1];
  7. Now save that and that will update the div to show the manager’s friendly name.

Let me share complete code for your reference so that it will be easier to just copy and paste without making any further efforts:

var has_mgr = !$isEmptyString(ctx.CurrentItem.Manager);
if(has_mgr == true) {
ms_outHtml.push(''
,'                                            <div id="ManagerField">'
); 
                                                var encodedMgr = $htmlEncode(ctx.CurrentItem.Manager);
                                                var displayMgr = Srch.U.getSingleHHXMLNodeValue(hhProps, "manager");
                                                if ($isEmptyString(displayMgr)) { displayMgr = encodedMgr }
												SP.SOD.executeFunc('sp.js', 'SP.ClientContext', getUserProperties);
function getUserProperties() {

SP.SOD.executeFunc('userprofile', 'SP.UserProfiles.PeopleManager', function() {
      // Replace the placeholder value with the target user's credentials.
    var targetUser = $get("ManagerValue").innerHTML.trim();

    // Get the current client context and PeopleManager instance.
    var clientContext = new SP.ClientContext.get_current();
    var peopleManager = new SP.UserProfiles.PeopleManager(clientContext);

    // Get user properties for the target user.
    // To get the PersonProperties object for the current user, use the
    // getMyProperties method.
    personProperties = peopleManager.getPropertiesFor(targetUser);

    // Load the PersonProperties object and send the request.
    clientContext.load(personProperties);
    clientContext.executeQueryAsync(onRequestSuccess, onRequestFail);
   });
 }
// This function runs if the executeQueryAsync call succeeds.
function onRequestSuccess() {
	$get("ManagerValue").innerHTML = personProperties.get_displayName();
}

// This function runs if the executeQueryAsync call fails.
function onRequestFail(sender, args) {
    console.log("Error: " + args.get_message());
}	
	
ms_outHtml.push(' '
,'                                                <span class="label">Manager :</span><div id="ManagerValue" class="ms-srch-ellipsis" title="', encodedOff ,'"> ', displayMgr ,' </div>'
,'                                            </div>'
); 
                                        }

Bingo !! This code does magic for us and get manager’s display name on basis of manager’s account name. Here is the screen shot what I got after running this code:

Hope my blog saved your time or guided you towards in direction of your goals.

Don’t forget to comment and like !

Happy SharePointing !!

Access SharePoint Online using Postman


There are number of ways to access the SharePoint API to fetch or update its resources. In all the ways, the authentication plays the important role in authorizing the access to get the information. As a developer, you may very much interested in using the PostMan tool for accessing the REST APIs.

Postman Chrome Extension
This is a developer friendly tool for handling the REST APIs from any platform. By using this tool we’ll fetch or update any information from SharePoint using REST API endpoints. We can get this utility from chrome extension and you can get that from this link PostMan Chrome Extension.

Postman & SharePoint Rest endpoints
If you are new to SharePoint REST API or you want to know more about REST endpoints in SharePoint; visit the link Get to know the SharePoint 2013 REST service.

Now we have some understanding about PostMan tool & SharePoint Rest API endpoints. Now we’ll start testing the SharePoint REST API with this tool.

Example

Let’s take a simple example like, getting the web title from the current site context. The equivalent syntax for retrieving the website’s title is

https://<SiteName&gt;.sharepoint.com/_api/web?$select=Title

After entering the above URL in the text-box in the URL text-box. We will get the Unauthorized exception on accessing the information. Because SharePoint Online is very much secured and that doesn’t allow anonymous users to access the information for their site. The below is the error message response, after sending the request.

.

UnAuthorized from Postman
Fig 1: UnAuthorized from Postman

To avoid the Unauthorized exception, we have to add some request header values to the API request. Authentication and Authorization of SharePoint Add-Ins gives the overview of authorizing the Add-ins to access SharePoint resources by the APIs.

Authentication Policies:

SharePoint online considers any one of the below three type of polices to authenticate the Add-In.

  • User Policy
  • Add-In Policy – We are using this policy to authenticate the external system to access SharePoint
  • User +Add-In Policy

Request Headers:

And, we require the following information in various requests to authenticate with SharePoint online site.

  • Client Id
  • Client Secret
  • Realm (Tenant Id)
  • Access Token

Authorize Postman to access SharePoint

To get authorized from external system, we should pass access-token value as a request header along with the REST API URL. Before that we have to get the access-token, for that we should generate Client Id and Secret information from the site by registering as an App only Add-In in SharePoint site. This is same as like registering add-in for Provider Hosted Add-In.

I have provided the steps below to get the Tenant Id, Access Token and data from SharePoint using PostMan utility.

Register Add-In

On initial stage, we have to register the Add-In in SharePoint, where we want to access the information. Follow the steps below to register the Add-In in SharePoint site.

  • Navigate and login to SharePoint online site.
  • Then navigate to the Register Add-In page by entering the url as

https://<sitename&gt;.SharePoint.com/_layouts/15/appregnew.aspx

  • On App Information section, click Generate button next to the Client Id and Client Secret textboxes to generate the respective values.
  • Enter Add-In Title in Title textbox
  • Enter AppDomian as a loclhost
  • Enter RedirectUri as a https://localhost
Register an Add-In
Fig 2: Register an Add-In
  • Click Create button, which registers the add-in and returns the success message with created information.
 Add-In Registration Successfull
Fig 3: Add-In Registration Successful

Grant Permissions to Add-In

Once the Add-In is registered, we have to set the permissions for that add-in to access the SharePoint data. We will set the Read permission level to the web scope, so that we will be able to read the web information.

  • Navigate to the SharePoint site
  • Then enter the URL https://<sitename&gt;.sharepoint.com/_layouts/15/appinv.aspx in the browser. This will redirect to Grant permission page.
  • Enter the Client ID(which we have generated earlier), in AppId textbox and click Lookup button. That will populate the value to other textboxes in Title, App Domain and Redirect Url
Fig 4: Set Permissions to Add-In
Fig 4: Set Permissions to Add-In
  • Now enter the below permission request in XML format.
    <AppPermissionRequests AllowAppOnlyPolicy="true">
        <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="Read" />
    </AppPermissionRequests>
  • Then click Create button. This will redirect to you page, where we have to trust the add-in to read items from website.
Fig 5: Trust Add-In
Fig 5: Trust Add-In

Note: If we want to access site collection or tenant level, we have add the xml accordingly

Retrieve the Tenant ID

Once we registered the Client Id and Secret with the permissions, we are ready to access the SharePoint information from external system or tools.

At first, we have to know the Tenant ID. Follow the below steps to obtain that information from postman. Postman helps to get the tenant Id by requesting the below url with Authorization header.

  • Launch Postman chrome extension.
  • Select Get Method
  • Enter the below URL in the “Request URL” textbox
    https://<sitename>/sharepoint.com/_vti_bin/client.svc/
  • Configure the below information in the header section to send along with the url requestMethod = Get
    Headers

    KEY SYNTAX VALUE
    Authorization Bearer Bearer
  • After applied the configuration, click Send button. The response returns lot of headers but ends with unauthorized access.
    Fig 6: Get Tenant ID from SharePoint Online
    Fig 6: Get Tenant ID from SharePoint Online

Generate the Access Token

In response header, we will get WWW-Authenticate as one of the header and that contains the necessary information required for next step. The realm value contains the tenant id for the SharePoint Online site and clientid value contains the resource information (we’ll use it later).

KEY SYNTAX VALUE
Content-Type application/x-www-form-urlencoded application/x-www-form-urlencoded

Body

KEY SYNTAX VALUE
grant_type client_credentials client_credentials
client_id ClientID@TenantID 4b4276d0-74cd-4476-b66f-e7e326e2cb93@10267809-adcb-42b6-b103-c7c8190b3fed
client_secret ClientSecret nuC+ygmhpadH93TqJdte++C37SUchZVK4a5xT9XtVBU=
resource resource/SiteDomain@TenantID 00000003-0000-0ff1-ce00-000000000000/spsnips.sharepoint.com@10267809-adcb-42b6-b103-c7c8190b3fed
  • After applying the configuration, click Send button. That will returns the response with the Access Token.
Fig 7: Postman response contains Access Token
Fig 7: Postman response contains Access Token

Once we are received the access token, its like we got the authorization to access the SharePoint data based on the permission applied in Grant Permission as Add-In section.

We have to pass the access token as “token_type access_token

Access the SharePoint resource

Now we have the access token, So we can now pass this token in Authorization header with the SharePoint REST API to get the information.

  • In Postman tool, add the below URL to retrieve the web title

https://<sitename&gt;.sharepoint.com/_api/web?$select=Title

  • Apply configurations in header
  • Method = POST
    Headers

    KEY SYNTAX VALUE
    Accept application/json;odata=verbose application/json;odata=verbose
    Authorization <token_type> <access_token> Bearer eyJ0eX….JQWQ
  • After applying the configuration, click Send button.
  • We will get the response successful as below if the permission xml applied correctly in appinv page. Otherwise we will get the access denied error message.
Retrieve the web tile from postman
Fig 8: Postman returns the web title in response

Happy SharePointing !

Hide All Day Event and Recurrence field from SharePoint Calendar in SharePoint


A very basic requirement under the SharePoint Calendar list is to hide All Day Event column from all the forms and libraries. It looks very easy but unfortunately there is not direct way of implementing this change. One have to install SharePoint designer in order to achieve this requirement. Let explain in this blog how this requirement will be materialized.

Problem:

Hide “All Day Event” column from the new form of the calendar list. This is the requirement in my case, may be you want to hide “Recurrence” column. Steps should be same in case of any out-of-box column.

You must have tried to find out the ways to hide this column from List settings > columns details. Firstly, this column is part of “Event” content type and will only be find under content type settings. Ok, seems easy, just visit CT settings and mark it hide.

Well, life is not so easy in this arena. These three columns are not allowed to update as these are handled by SharePoint itself.

Solution:

  1. Install SharePoint Designer on your machine. It works for all version of sharepoint so SPD is the best option to make changes.
  2. Open the SharePoint site where Calendar list resides.
  3. Click on the List and Libraries sections.
  4. Find out where the Calendar list of present and click to open this list.
  5. While you are under List details screen on right portion of the screen, find out Content types section.
  6. There must be “Event” content type visible under the list content types. Click on the content type “Event” to open its details.
  7. Now under customization section, click “Edit content type columns” option. This will navigate you to a columns details page.
  8. On this screen, select “All Day Event”.
  9. Under Property column you can see three options. From the drop down select Hidden(Will not appear in forms)
  10. Or, When you have selected “All Day Event” column, navigate to top ribbon and select “Administrative Web Page”
  11. It will navigate you on a browser and open a page where you can easily select option: Hidden(Will not appear in forms)

I hope this information will be helpful and save lot of time. Do not forget to like this article if it was valuable information for you.

Thanks for your valuable time !

Happy SharePointing :).

Blog post filtering based on category not working


Hello,

Recently, I faced an issue while working with SP Online blog site. This issue applies to other versions of SharePoint as well.

If you are working on blogs on SharePoint platforms, you might have faced an issue when trying to filter blog posts based on category by hitting the category link shown on the Quick Launch or the category associated to the post. Doing so returns ALL posts what ever the category you asked to display (as shown below).

Steps To Reproduce:

There could be multiple reasons of this issue. Mainly, “Category.aspx” page is responsible for rendering this kind of display. You must be very cautious when doing any changes on this page. This page does not have any check-in/check-out or publishing feature so you can not revert to previous version of this page. In case you broke the linking between blog tools and other web parts it is very hard to restore it in working stage. Most of the blog sites recommend you to recreate blog site again(you will loose all blogs).

In my case, I landed up to this issues by following below two steps:

  • Go to the Posts list settings to enable Content Approval
  • Then disable the Content Approval

This has been confirmed and escalated for resolution. It appears this is because the XML query is being modified by removing the category filtering.

However, in the mean time, here is a workaround.

WORKAROUND

  • Create a blog site and do not enable the Content Approval(This step is only for getting unmodified code for reference)
  • Using SharePoint Designer open the new blog site and browse to All files\Lists\Categories and edit the category.aspx page

 

  • Open your faulty blog site and do the same (edit the category.aspx page)
  • Locate the following code (NOTE: the GUID is the specific one to your environment)

<View Name=”{F28F9AA8-7F35-4912-BAF5-1A225F33B484}” Type=”HTML” Hidden=”TRUE” ReadOnly=”TRUE” FreeForm=”TRUE” ModerationType=”HideUnapproved” DisplayName=”” Url=”/Lists/Categories/Category.aspx” Level=”1″ BaseViewID=”8″ ContentTypeID=”0x” ><Query><OrderBy><FieldRef Name=”PublishedDate” Ascending=”FALSE”/><FieldRef Name=”ID” Ascending=”FALSE”/></OrderBy></Query><ViewFields><FieldRef Name=”Title”/><FieldRef Name=”Body”/><FieldRef Name=”Author”/><FieldRef Name=”PostedByWithDate”/><FieldRef Name=”CategoryWithLink”/><FieldRef Name=”Permalink”/><FieldRef Name=”EmailPostLink”/><FieldRef Name=”NumCommentsWithLink”/><FieldRef Name=”PublishedDate”/><FieldRef Name=”PostCategory”/><FieldRef Name=”AverageRating”/><FieldRef Name=”RatedBy” Explicit=”TRUE”/><FieldRef Name=”Ratings” Explicit=”TRUE”/></ViewFields><RowLimit Paged=”TRUE”>10</RowLimit><JSLink>sp.ui.blogs.js</JSLink><XslLink>blog.xsl</XslLink><Toolbar Type=”None”/></View>

  • Add the following code after the </OrderBy> and before the </Query> tags

<Where><And><And><In><FieldRef Name=”PostCategory” LookupId=”TRUE”/><Values><Value Type=”Integer”><IfEqual><Expr1><GetVar Scope=”Request” Name=”CategoryId”/></Expr1><Expr2/><Then>-1</Then><Else><GetVar Scope=”Request” Name=”CategoryId”/></Else></IfEqual></Value></Values></In><Leq><FieldRef Name=”PublishedDate”/><Value Type=”DateTime”><Today/></Value></Leq></And><Eq><FieldRef Name=”_ModerationStatus”/><Value Type=”ModStat”>0</Value></Eq></And></Where>

  • which then looks like

<View Name=”{F28F9AA8-7F35-4912-BAF5-1A225F33B484}” Type=”HTML” Hidden=”TRUE” ReadOnly=”TRUE” FreeForm=”TRUE” ModerationType=”HideUnapproved” DisplayName=”” Url=”/Lists/Categories/Category.aspx” Level=”1″ BaseViewID=”8″ ContentTypeID=”0x” ><Query><OrderBy><FieldRef Name=”PublishedDate” Ascending=”FALSE”/><FieldRef Name=”ID” Ascending=”FALSE”/></OrderBy><Where><And><And><In><FieldRef Name=”PostCategory” LookupId=”TRUE”/><Values><Value Type=”Integer”><IfEqual><Expr1><GetVar Scope=”Request” Name=”CategoryId”/></Expr1><Expr2/><Then>-1</Then><Else><GetVar Scope=”Request” Name=”CategoryId”/></Else></IfEqual></Value></Values></In><Leq><FieldRef Name=”PublishedDate”/><Value Type=”DateTime”><Today/></Value></Leq></And><Eq><FieldRef Name=”_ModerationStatus”/><Value Type=”ModStat”>0</Value></Eq></And></Where></Query><ViewFields><FieldRef Name=”Title”/><FieldRef Name=”Body”/><FieldRef Name=”Author”/><FieldRef Name=”PostedByWithDate”/><FieldRef Name=”CategoryWithLink”/><FieldRef Name=”Permalink”/><FieldRef Name=”EmailPostLink”/><FieldRef Name=”NumCommentsWithLink”/><FieldRef Name=”PublishedDate”/><FieldRef Name=”PostCategory”/><FieldRef Name=”AverageRating”/><FieldRef Name=”RatedBy” Explicit=”TRUE”/><FieldRef Name=”Ratings” Explicit=”TRUE”/></ViewFields><RowLimit Paged=”TRUE”>10</RowLimit><JSLink>sp.ui.blogs.js</JSLink><XslLink>blog.xsl</XslLink><Toolbar Type=”None”/></View>

  • Save the page, the category filtering is working again

To finalize the operation, open the category.aspx page with your web browser to remove the Blog Tools webpart which will be in error and add it again.

Happy SharePointing !!!

Create a workflow with elevated permissions by using the SharePoint Workflow platform


Hello,

There are various reasons that one requires elevated privileges to list/site workflow. Most common use case is, if workflow need to fetch data from some other list/library at site collection/sub site level.

SharePoint App-Only is the older, but still very relevant, model of setting up app-principals. This model works for both SharePoint Online and SharePoint 2013/2016 on-premises and is ideal to prepare your applications for migration from SharePoint on-premises to SharePoint Online. Below steps show how to setup an app principal with tenant full control permissions, but obviously you could also grant just read permissions using this approach.

Applies To
  • SharePoint 2013/2016
  • SharePoint Online

This blog is also targets resolution of following error:

The Workflow was Suspended with Unauthorized HTTP

OR

Unauthorized HTTP to /_vti_bin/client.svc/web/lists

Issue:

By default, the SharePoint workflow doesn’t have sufficient permission to access the SharePoint lists, and this process requires a full control permission level.

Some important point before enabling App Step:

  • To allow the workflow to use APP permissions, you must be a Site Owner or Site Collection Administrator.
  • App Step can be activated at Tenant/Site Collection/Web.
  • The Workflow Manager platform must be configured properly to be able to activate “Workflows can use app permissions” feature.
  • The App Management Service must be configured to be able to grant a full control permission to a workflow.
  • App step provides the workflow authorization for its Identity as a Full Control and ignores the current user permission.
  • The SharePoint 2010 workflow is not supported in App Step,
  • If you don’t elevate the permissions for the SharePoint Workflow, The App Step will be disabled in the SharePoint Designer.

Solution:

To begin the elevation process, follow below steps:

  1. Allow workflow to use app permissions
  2. Grant full control permission to a workflow
  3. Develop the workflow actions inside an App Step using SharePoint Designer

Lets deep dive in details of all three steps mentioned above.

I. Allow workflow to use app permissions: 

The Workflow Manager platform must be configured properly to be able to activate “Workflows can use app permissions” feature. This feature is scoped to the web level feature so in case of site collection or web. This feature is available under web features.

  • Open the SharePoint Site > Site Settings.
  • Below Site Actions > Select Manage site features.
  • Activate Workflows can use app permissions feature.

In above step, we have ensured that after activating this feature, workflow can able to use permission which we will define under next step.

II.  Grant full control permission to a workflow

  • Open the SharePoint Site Collection > Site Settings >Below Users and Permissions > Click on Site App Permissions.

  • Copy the client section of the App Identifier. The App Identifier is the identifier Guid between the last “|” and the “@” sign, as shown below.

  • Navigate to grant permission to an app page by browsing the “appinv.aspx” page of the web site.

http://siteurl/_layouts/15/appinv.aspx.

  • Paste the client section of App Identifier to the App Id field.
  • Click Lookup to fetch the required info.
  • The App Management Service must be configured to be able to lookup your identifier. If the App Management Service is not installed you will get the below error when you clicked on Lookup button.

  • Paste the below APP Permissions Request XML to grant full control permission. Make sure tags and attribute names are in correct casing because small case will not be detected.

<AppPermissionRequests AllowAppOnlyPolicy="true">
<AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="FullControl">
</AppPermissionRequest></AppPermissionRequests>

 

 

  • You will then be asked to trust the Workflow app, Click Trust It.

III. Develop the workflow actions inside an App Step using SharePoint Designer

The App Step option will be disabled in the SharePoint Designer, in case you are not followed above mentioned steps. Using App step will allow the workflow to be authorized with its identity as a Full Control and ignore the current user permissions. This is will ensure that the workflow will be executed successfully in case the current user has no permissions.

Good to Go !! Once it is added it to workflow, it is easy to write any action under it.

NOTE: If you still see app step as disabled then close the SPD instance and reopen it. If still not see it enabled, then make sure you have done above steps in correct site collection/web.

NOTE: Make sure, Under Workflow Settings >  Uncheck the “Automatic updates to workflow status to the current stage name“, then click Publish.

If you didn’t uncheck “Automatic updates to workflow status to the current stage name“, the current user will require Edit permission on the list to can edit the workflow status.

Happy SharePointing !!

%d bloggers like this: