Saturday, 5 June 2021

Microsoft Flow: query cannot be completed because the number of lookup columns it contains exceeds the lookup column threshold

You'll get this error when you are using Microsoft Flow and if you want to get an item from SharePoint List which has more than 12 lookup columns.

Error:

The query cannot be completed because the number of lookup columns it contains exceeds the lookup column threshold.

clientRequestId: 45c548ed-6957-45ff-ae6b-2d19887a92ad
serviceRequestId: 45c548ed-6957-45ff-ae6b-2d19887a92ad

Why do we get this error?

The error is causing with SQL Server. Each lookup requires a join with another table within SQL Server so Microsoft decided to maximize the number of lookups that can be made to avoid performance degradation.

Initially the limit was set to 8, but since the SharePoint 2013 Post June 2013 CU update, Microsoft has increased this limit to 12.

Columns that are defined as lookup columns?

Below are the column types are defined as lookup columns:

  • Standard Lookup columns
  • Managed metadata columns
  • People and groups columns (These also include the Created by and Modified by fields, see below!)
  • Workflow Status columns
OOTB Lookup columns:
  • Created by
  • Modified by
  • Name (linked to Document)
  • Link (Edit to edit item)
  • Name (linked to Document with edit menu)
  • Type (icon linked to document)
The solution is to create a view in your SharePoint list that has a maximum of 11 lookup columns. Then in Power Automate you add that view and that resolves the issue.

Ref links:

Sunday, 11 April 2021

Connect-PnPOnline : The term 'Connect-PnPOnline' is not recognized as the name of a cmdlet, function, script file, or operable program.

Why PnP PowerShell Module ?

PnP PowerShell internally uses the Client-Side Object model code for its operations hence we can reduce the number of lines in our scripts by utilizing its built-in cmdlets and reduce the complexity of scripting implementations.  

When you are trying to connect the SharePoint Online and don't have the PnP PowerShell module for SharePoint Online on the local machine, you will see this error.

Connect-PnPOnline : The term 'Connect-PnPOnline' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.


So, to get rid of this error, you must install "SharePointPnPPowerShellOnline" module.

Install SharePoint Online PnP PowerShell Module:

Before you install the module, you need to download and install Windows Management Framework 5.1 from https://www.microsoft.com/en-us/download/details.aspx?id=54616 on your operating system Windows 7/8, Windows 2008 or in Windows 2012/R2 environments. Restart your machine to complete the installation and follow the below.

1. Open SharePoint Online Management Shell or Windows PowerShell as Administrator and Run:
Install-Module SharePointPnPPowerShellOnline

This command will install the recent version of the PnP PowerShell Module.

If you are not able to download the module due to the below error and If you want to install on a machine without an internet connection and make the cmdlets automatically available in PowerShell, then follow the below steps:

Go to the computer with which has internet connection and enter below command on Windows PowerShell:
Save-Module -Name SharePointPnPPowerShellOnline -Path [c:\foldertosavemoduleto]


In the path specified a folder will be created called SharePointPnPPowerShellOnline. Copy this folder and all its contents to the target computer.

If you want to have the module only available for a specific user, copy the folder and its contents to
c:\users\[username]\documents\windowspowershell\modules

Note: that you might have to create this folder structure

If you want the module to be available for all users, copy the folder and its contents to 
c:\program files\windowspowershell\modules

Once it is done check if SharePoint Online PnP PowerShell Module is Installed and then connect to site.

Sunday, 14 February 2021

Document library item view/edit properties screen populates blank screen in SharePoint Online

Recently we have migrated SharePoint 2010 site to SharePoint Online and after the migration we noticed an issue in some of the doc libraries. Contents can be uploaded, but the prompt to fill out properties is not happening and when selecting to edit properties, the fields to populate/amend is not appearing. Edit shows as a blank screen. See this below screen.



We have changed the view from modern to classic list view where I can see all the fields but was not able to update the item due to 'Copy Source' field which is OOTB column.


The root cause is the read only column "Copy Source" being added to the list's content type "Document". Removing the field from content type, classic view starts working. However in modern view still prompts the blank screen.

We fixed the issue in Modern UI by removing below fields from Document Content Type using PowerShell script.

like wise we have the same issue with Picture library, Custom list, Links list as well. 

Below is the script which will remove the read-only fields from content types: Document, Link, Item and Picture from the associated library/list.

Note: OOTB field IDs are unique for all the lists/libraries in site collection.

#Load SharePoint CSOM Assemblies
Add-Type -Path "F:\microsoft.sharepointonline.csom.16.1.8412.1200\lib\net45\Microsoft.SharePoint.Client.dll"
Add-Type -Path "F:\microsoft.sharepointonline.csom.16.1.8412.1200\lib\net45\Microsoft.SharePoint.Client.Runtime.dll"
Add-Type -Path "F:\microsoft.sharepointonline.csom.16.1.8412.1200\lib\net45\Microsoft.SharePoint.Client.Taxonomy.dll"

Try
{
$WebURL="https://tenant.sharepoint.com/sites/ProjectSites/PC0296/"

$UserName="liakathali.mohammed@domain.com"
$Password ='XXXXXXXXX'

$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName,(ConvertTo-SecureString $Password -AsPlainText -Force))

#Set up the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($WebURL)
$Ctx.Credentials = $Credentials
$Ctx.ExecuteQuery()

#Get Lists from the web
$Ctx.Load($Ctx.Web.Lists)
$Ctx.executeQuery()

#Impacted content types
$ContentTypeName="Document"
$ContentTypeName1="Link"
$ContentTypeName2="Picture"
$ContentTypeName3="Item"

#Get Lists from the web
$Lists = $Ctx.Web.Lists
$Ctx.Load($Lists)
$Ctx.ExecuteQuery()

#Loop through each document library and Get the Title
    Foreach ($list in $Lists)
    {
    Write-host $list.Title
      if(($list.Title -eq "Correspondence") -or ($list.Title -eq "Supporting Documentation") -or ($list.Title -eq "Project Plan"))
      {
        #Get contenttype from list
         $ctypecoll = $list.ContentTypes #| Where {$_.Name -Match $ContentTypeName} #-ErrorAction SilentlyContinue
         $Ctx.Load($ctypecoll)  
         $Ctx.ExecuteQuery()
         $ctypecoll.Name
 
        #Check if the content type exists in the list      
         $ContentType = $ctypecoll | Where {$_.Name -eq $ContentTypeName}
         If($ContentType -eq $Null)
         {
             Write-host "Content Type '$ContentTypeName' doesn't exists in '$list'" -f Yellow
             Return
         }

        write-host -f Green "Content Type ID:" $ContentType.Name
        write-host -f Green "Content Type ID:" $ContentType.Id

        #Get the column to delete from content type
         $ContentTypeFieldColl =  $ContentType.Fields
         $Ctx.Load($ContentTypeFieldColl)
         $Ctx.ExecuteQuery()
        
         #Get the field link from content type
         $FieldLinkColl = $ContentType.FieldLinks
         $Ctx.Load($FieldLinkColl)
         $Ctx.ExecuteQuery()

        #Get Author Field
         $author = $FieldLinkColl.GetById('1df5e554-ec7e-46a6-901d-d85a3881cb18')
         $Ctx.Load($author)
         $Ctx.ExecuteQuery()
         write-host $author.Name
         $author.DisplayName
 
         #Get Editor Field
         $editor = $FieldLinkColl.GetById('d31655d1-1d5b-4511-95a1-7a09e9b75bf2')
         $Ctx.Load($editor)
         $Ctx.ExecuteQuery()
         write-host $editor.Name 

         #Get Copy Source Field
         $copysource = $FieldLinkColl.GetById('6b4e226d-3d88-4a36-808d-a129bf52bccf')
         $Ctx.Load($copysource)
         $Ctx.ExecuteQuery()
         write-host $copysource.Name

         #Get Checked Out To Field
         $checkedoutto = $FieldLinkColl.GetById('3881510a-4e4a-4ee8-b102-8ee8e2d0dd4b')
         $Ctx.Load($checkedoutto)
         $Ctx.ExecuteQuery()
         write-host $checkedoutto.Name 

         $author.DeleteObject()
         $editor.DeleteObject()
         $copysource.DeleteObject()
         $checkedoutto.DeleteObject()
         $ContentType.Update($false)
         $ctx.ExecuteQuery()

         Write-host "Columns" $author.Name "," $editor.Name "," $copysource.Name "," $checkedoutto.Name "Deleted from list:" $list.Title "Successfully!" -ForegroundColor Green
       }

      elseif ($list.Title -eq "Photos")
      {
       #Get contenttype from list
        $ctypecoll = $list.ContentTypes
        $Ctx.Load($ctypecoll)  
        $Ctx.ExecuteQuery()
        $ctypecoll.Name 

       #Check if the content type exists in the list      
         $ContentType = $ctypecoll | Where {$_.Name -eq $ContentTypeName2}
         If($ContentType -eq $Null)
         {
             Write-host "Content Type '$ContentTypeName2' doesn't exists in '$list'" -f Yellow
             Return
         }
        write-host -f Green "Content Type ID:" $ContentType.Id

        #Get the column to delete from content type
         $ContentTypeFieldColl =  $ContentType.Fields
         $Ctx.Load($ContentTypeFieldColl)
         $Ctx.ExecuteQuery() 

        #Get the field link from content type
         $FieldLinkColl = $ContentType.FieldLinks
         $Ctx.Load($FieldLinkColl) 

        #Get Author Field
         $author = $FieldLinkColl.GetById('1df5e554-ec7e-46a6-901d-d85a3881cb18')
         $Ctx.Load($author)
         $Ctx.ExecuteQuery()
         write-host $author.Name 

         #Get Editor Field
         $editor = $FieldLinkColl.GetById('d31655d1-1d5b-4511-95a1-7a09e9b75bf2')
         $Ctx.Load($editor)
         $Ctx.ExecuteQuery()
         write-host $editor.Name 

         #Get Copy Source Field
         $copysource = $FieldLinkColl.GetById('6b4e226d-3d88-4a36-808d-a129bf52bccf')
         $Ctx.Load($copysource)
         $Ctx.ExecuteQuery()
         write-host $copysource.Name 

         #Get Checked Out To Field
         $checkedoutto = $FieldLinkColl.GetById('3881510a-4e4a-4ee8-b102-8ee8e2d0dd4b')
         $Ctx.Load($checkedoutto)
         $Ctx.ExecuteQuery()
         write-host $checkedoutto.Name 

         $author.DeleteObject()
         $editor.DeleteObject()
         $copysource.DeleteObject()
         $checkedoutto.DeleteObject()
         $ContentType.Update($false)
         $Ctx.ExecuteQuery()
         Write-host "Columns" $author.Name "," $editor.Name "," $copysource.Name "," $checkedoutto.Name "Deleted from list:" $list.Title "Successfully!" -ForegroundColor Green
      } 

      elseif ($list.Title -eq "Helpful Links")
      {
       #Get contenttype from list
        $ctypecoll = $list.ContentTypes
        $Ctx.Load($ctypecoll)  
        $Ctx.ExecuteQuery()
        $ctypecoll.Name 

       #Check if the content type exists in the list      
         $ContentType = $ctypecoll | Where {$_.Name -eq $ContentTypeName1}
         If($ContentType -eq $Null)
         {
             Write-host "Content Type '$ContentTypeName1' doesn't exists in '$list'" -f Yellow
             Return
         }
        write-host -f Green "Content Type ID:" $ContentType.Id

        #Get the column to delete from content type
         $ContentTypeFieldColl =  $ContentType.Fields
         $Ctx.Load($ContentTypeFieldColl)
         $Ctx.ExecuteQuery()

        #Get the field link from content type
         $FieldLinkColl = $ContentType.FieldLinks
         $Ctx.Load($FieldLinkColl) 

        #Get Author Field
         $author = $FieldLinkColl.GetById('1df5e554-ec7e-46a6-901d-d85a3881cb18')
         $Ctx.Load($author)
         $Ctx.ExecuteQuery()
         write-host $author.Name 

         #Get Editor Field
         $editor = $FieldLinkColl.GetById('d31655d1-1d5b-4511-95a1-7a09e9b75bf2')
         $Ctx.Load($editor)
         $Ctx.ExecuteQuery()
         write-host $editor.Name 

         $author.DeleteObject()
         $editor.DeleteObject()
         $ContentType.Update($false)
         $ctx.ExecuteQuery()
         Write-host "Columns" $author.Name "," $editor.Name "Deleted from list:" $list.Title "Successfully!" -ForegroundColor Green
      }

      elseif ($list.Title -eq "Custom List")
      {
       #Get contenttype from list
        $ctypecoll = $list.ContentTypes
        $Ctx.Load($ctypecoll)  
        $Ctx.ExecuteQuery()
        $ctypecoll.Name 

        #Check if the content type exists in the list      
         $ContentType = $ctypecoll | Where {$_.Name -eq $ContentTypeName3}
         If($ContentType -eq $Null)
         {
             Write-host "Content Type '$ContentTypeName3' doesn't exists in '$list'" -f Yellow
             Return
         }
        write-host -f Green "Content Type ID:" $ContentType.Id 

        #Get the column to delete from content type
         $ContentTypeFieldColl =  $ContentType.Fields
         $Ctx.Load($ContentTypeFieldColl)
         $Ctx.ExecuteQuery()

        #Get the field link from content type
         $FieldLinkColl = $ContentType.FieldLinks
         $Ctx.Load($FieldLinkColl)

        #Get Author Field
        $author = $FieldLinkColl.GetById('1df5e554-ec7e-46a6-901d-d85a3881cb18')
         $Ctx.Load($author)
         $Ctx.ExecuteQuery()
         write-host $author.Name 

         #Get Editor Field
         $editor = $FieldLinkColl.GetById('d31655d1-1d5b-4511-95a1-7a09e9b75bf2')
         $Ctx.Load($editor)
         $Ctx.ExecuteQuery()
         write-host $editor.Name 

         $author.DeleteObject()
         $editor.DeleteObject()
         $ContentType.Update($false)
         $ctx.ExecuteQuery()
         Write-host "Columns" $author.Name "," $editor.Name "Deleted from list:" $list.Title "Successfully!" -ForegroundColor Green
      }
    }
   }
    Catch {

         write-host -f Red "Error Deleting Column from Content Type!" $_.Exception.Message
     }

Friday, 12 February 2021

Coercion Failed: Input cannot be null for this coercion in SharePoint Online list

We have list workflow configured in our SharePoint Online site, to send email on list item created. However our workflow is keep failing and it's getting cancelled with the below error message which we found on workflow history for the particular workflow instance.

Coercion Failed: Input cannot be null for this coercion


Root Cause:

When we look at email body, we noticed a multiple selection field which is causing the issue and it is set to return as "Choices, Comma Delimited" value. Whenever this field value returns null, then our workflow gets cancelled with the above error. (I used 'log to workflow history' action to verify the values)

Solution:

To fix this issue we have changed the return type for the field from "Choices, Comma Delimited" to "As String" and then workflow started working without any error.


Thursday, 26 November 2020

Publish InfoPath form to different SharePoint list

Using InfoPath Designer, we cannot change the publish URL, If you want to deploy the InfoPath form from one list to another list in the same site or a different SharePoint site hence you need to update the publish URL manually by updating the manifest file of the InfoPath form.

Below are the steps to UPDATE Manifest.xsf file:

  1. From the source list Open the InfoPath form using designer and go to File menu, select Save As option to save the InfoPath form. You will be saving a .xsn file.
  2. You cannot use the old form as-is, because it was bound to the list by its GUID, and the new list most likely has a different GUID.
  3. Rename the file from .xsn to .cab(Template.xsn to Template.cab).
  4. Extract the file using Winzip to a folder.
  5. Go to the extracted folder and open the file Manifest.xsf.
  6. Search for your current site/list URL and replace it with the new site/list URL.
  7. In addition to changing the site URL in this file, you will also need to change the GUID of each list referenced in the InfoPath form so that it matches the value in the target environment. To do that, search for all lines in manifest.xsf with "sharePointListID=" and change the GUID that follows.
  8. You may also need to change the GUID value(s) for content types as well. Search through the manifest.xsf file looking for non-null values following "contentTypeID=" and change them to the GUID value in the target environment as well.

Note: To find the correct GUID of the List, ContentTypeID you will need to go to the target list --> Click on "Customize in InfoPath" from list tools, and do Save As to save the InfoPath Form. Once you save the form you can change the extension to .cab and extract the CAB file. From the extracted folder you can Open the target list Manifest.xsf file in notepad and note the GUIDs of the Lists and ContentTypeID.

If you are using Modern view then you need to navigate to List Settings--> form settings and follow the same instructions.

     9. Now we have the updated manisfest file which is pointing to the new site. Now we need to make a .XSN file out of the extracted files. You can use CabMaker tool to create the .xsn file

Download the tool from : https://github.com/sapientcoder/CabMaker/releases 

    10. Now right click on .XSN file, select design & under File menu select publish. Now you would be able to see the publish URL pointing to your new site/list.

    11. Go ahead and publish the form.

If you don't have the MakeCab tool then you can create the XSN file from the extracted folder using makecab.exe from the command prompt. Below is the content of directive file(ddf.txt)

;************************************************************
; MSDN Sample Source Code MakeCAB Directive file example
;************************************************************ .OPTION EXPLICIT
; change the value of the caninet name for example myInfoPath.xsn
;***************************************************************** ;******************************************************************
; change the value of the Disk Directory Template value to the directory you want to store the xsn file into,,
.Set CabinetNameTemplate=NewTemplate.XSN ;**********************************************************************************************
;********************************************************************************************** .set DiskDirectoryTemplate="C:\Users\Liakath\Documents\InfoPath" .Set Cabinet=on .Set Compress=on
"C:\Users\Liakath\Documents\InfoPath\Template\Audit Results5.xsd"
;******************************************************* ; Just List All the files to be added in the xsn file ;******************************************************* "C:\Users\Liakath\Documents\InfoPath\Template\Audit Results6.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\Choices Data Connection.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\Audit Results7.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\Audit Results8.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\Audit Results9.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\choices.xml"
"C:\Users\Liakath\Documents\InfoPath\Template\Close.xsl" "C:\Users\Liakath\Documents\InfoPath\Template\EmpInfo10.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\EmpInfo11.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\EmpInfo12.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\EmpInfo13.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\EmpInfo9.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\EmpInfo14.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\EmpInfo15.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\EmpInfo6.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\EmpInfo7.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\EmpInfo8.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\FormTypeSelection.xsl"
"C:\Users\Liakath\Documents\InfoPath\Template\ExpenseCodes5.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\ExpenseCodes6.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\ExpenseCodes7.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\ExpenseCodes8.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\ExpenseCodes9.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\LiabRequestTypeAdmin.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\GetUserProfileByName1.xml" "C:\Users\Liakath\Documents\InfoPath\Template\GetUserProfileByName3.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\GetUserProfileByName4.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\GetUserProfileByName5.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\Liability.xsl"
"C:\Users\Liakath\Documents\InfoPath\Template\LiabRequestTypes1.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\LiabRequestTypeAdmin1.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\LiabRequestTypeAdmin2.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\LiabRequestTypeAdmin3.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\LiabRequestTypeAdmin4.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\LiabRequestTypes.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\Office Number Translation7.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\LiabRequestTypes2.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\LiabRequestTypes3.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\LiabRequestTypes4.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\manifest.xsf" "C:\Users\Liakath\Documents\InfoPath\Template\Office Number Translation5.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\Office Number Translation6.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\PropRequestTypes3.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\Office Number Translation8.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\Office Number Translation9.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\Property.xsl" "C:\Users\Liakath\Documents\InfoPath\Template\PropRequestTypes.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\PropRequestTypes1.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\PropRequestTypes2.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\PropRequestTypes4.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\schema.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\PropRequestTypesAdmin5.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\PropRequestTypesAdmin6.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\PropRequestTypesAdmin7.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\PropRequestTypesAdmin8.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\PropRequestTypesAdmin9.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\sampledata.xml" "C:\Users\Liakath\Documents\InfoPath\Template\Save.xsl" "C:\Users\Liakath\Documents\InfoPath\Template\schema1.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\Suspended Reason6.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\schema2.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\schema3.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\schema4.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\Status.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\Status1.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\Status2.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\Status3.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\Status4.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\Suspended Reason5.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\WCRequestTypes9.xsd"
"C:\Users\Liakath\Documents\InfoPath\Template\Suspended Reason7.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\Suspended Reason8.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\Suspended Reason9.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\template.xml" "C:\Users\Liakath\Documents\InfoPath\Template\upgrade.xsl" "C:\Users\Liakath\Documents\InfoPath\Template\WCRequestTypes5.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\WCRequestTypes6.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\WCRequestTypes7.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\WCRequestTypes8.xsd"
;*********************
"C:\Users\Liakath\Documents\InfoPath\Template\WCRequestTypesAdmin10.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\WCRequestTypesAdmin6.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\WCRequestTypesAdmin7.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\WCRequestTypesAdmin8.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\WCRequestTypesAdmin9.xsd" "C:\Users\Liakath\Documents\InfoPath\Template\WorkComp.xsl" ;********************* ; End of the File

Sunday, 22 November 2020

Enable Breadcrumb/Navigation up in SharePoint Online

SharePoint 2010 has Breadcrumb option which helps us to know in which level we are in. However this feature has been disabled in SharePoint 2013 and next versions by default. But this can be enabled in Out-Of-The-Box seatle / oslo master page. 

Connect your SharePoint Online Site using SharePoint Designer 2013 and take copy of the master page and paste it.

1. Open the master page in Advanced Mode, search for the below class and remove the style attribute. 

<div class="ms-breadcrumb-dropdownBox" style="display:none;"> 

2. Search for the tag with Id "DeltaBreadcrumbDropDown" essentially next to the preceding tag and remove the visible ="false" or change it as true.

<SharePoint:AjaxDelta id="DeltaBreadcrumbDropdown" runat="server">   <SharePoint:PopoutMenu

    Visible="false"

    runat="server"

    ID="GlobalBreadCrumbNavPopout"

    Icon="/_layouts/15/images/spcommon.png?rev=23"

3. Save the master page, Check in and Publish as Major version.

That's it. Go back to your SharePoint Site and refresh it. You should have a BreadCrumb in the top navigation bar.

Before the masterpage change


After the Master page change

How to upload the SharePoint 2010 site template in SharePoint Online

Moving site templates between different versions, such as SharePoint 2010 to SharePoint 2013, is not supported. Moving between SharePoint Servers 2013, 2016, and 2019 should work. 

You will get below error when you try to upload/activate the SharePoint 2010 template/solution in SharePoint Online version.

In order to export the site with content, navigate to Site Settings in SharePoint and click “Save site as a template”. 

Remember to check off "Include Content" before hitting OK to be sure you include the content. If you have a lot of content and want to do a dry-run first, then you can skip including the content the first time around.

Note: If you don't have the ability to save the site as template then below reasons why you can not save site as template.
a. You have publishing feature enabled
b. Custom script is not allowed in tenant level(applies to SPO)
c. You have group connected site or communication site.

To allow custom scripts, you need to run the below script using SharePoint Online Management Shell:
$AdminCenterURL = "https://tenant-admin.sharepoint.com/"
$SiteURL="https://tenant.sharepoint.com/Sites/url"

#Connect to SharePoint Online
Connect-SPOService -url $AdminCenterURL -Credential (Get-Credential)

#Disable DenyAddAndCustomizePages Flag
Set-SPOSite $SiteURL -DenyAddAndCustomizePages 0

It can take up to 24 hours before the setting is enabled. After this you should be able to save as a template. or you can directly access this using below URL:

http://tenant.sharepoint.com/sites/url/_layouts/_savetmpl.aspx

Once you save the site as template, you can download it from the solution gallery..

Click the name of the package to save it on your local computer.

Now we have the downloaded solution package which is a 2010 version and it is not compatible as a 2013 site template in SharePoint Online.However we make the package compatible with SharePoint Online by changing the UI Version from the Onet.xml file by extracting the solution file.
  1. Change the extension of the solution package from WSP to CAB and extract is using 7-zip or winrar.
  2. Open the Onet.xml file into text editor from WebTemplate folder.
  3. The first row of he file will look something like below.
<Project Title="ProjectTemplate111120" Revision="0" UIVersion="4" EnableMinimalDownload="FALSE" SiteLogoUrl="" SiteLogoDescription="" xmlns="http://schemas.microsoft.com/sharepoint/">

Change the UIVersion number 4 to 15.

<Project Title="ProjectTemplate111120" Revision="0" UIVersion="15" EnableMinimalDownload="FALSE"  SiteLogoUrl="" SiteLogoDescription="" xmlns="http://schemas.microsoft.com/sharepoint/">

Now we are good to packing up the previously extracted to a new WSP file. You can use CabMaker, to create the WSP file.
Download the CabMaker from here

Upload the solution to SharePoint Online:

Navigate to the site collection in SharePoint Online you want to provision the site, and once again navigate to the Solution Gallery from Site Settings. Upload your solution and make sure it’s activated.

Note: If you see any error like "Missing site collection feature IDs" then please activate them using the below PowerShell. In case if the reported features are not important for the solution and the quick fix is going back to Onet.xml, finding the referred GUID’s and remove the entries/lines from the file. Once saved you have to go back and re-create the CAB/WSP file and upload the new one.

#  -> $sUserName: User Name to connect to the SharePoint Online Site Collection.

#  -> $sPassword: Password for the user.

#  -> $sSiteColUrl: SharePoint Online Site Collection

#  -> $sFeatureGuid: GUID of the feature to be enabled     

    $host.Runspace.ThreadOptions = "ReuseThread"     

    #Definition of the function that allows to enable a SPO Feature
    function Enable-SPOFeature
    {
        param ($sSiteColUrl,$sUserName,$sPassword,$sFeatureGuid)
        try
        {    
            #Adding the Client OM Assemblies        
            Add-Type -Path "F:\microsoft.sharepointonline.csom.16.1.8412.1200\lib\net45\Microsoft.SharePoint.Client.dll"
            Add-Type -Path "F:\microsoft.sharepointonline.csom.16.1.8412.1200\lib\net45\Microsoft.SharePoint.Client.Runtime.dll"

            #SPO Client Object Model Context

            $spoCtx = New-Object Microsoft.SharePoint.Client.ClientContext($sSiteColUrl) 

            $spoCredentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($sUsername, $sPassword)  

            $spoCtx.Credentials = $spoCredentials      

            Write-Host "----------------------------------------------------------------------------"  -foregroundcolor Green

            Write-Host "Enabling the Feature with GUID $sFeatureGuid !!" -ForegroundColor Green

            Write-Host "----------------------------------------------------------------------------"  -foregroundcolor Green

            $guiFeatureGuid = [System.Guid] $sFeatureGuid

            #############################################

            # todo: change object: $spoSite=$spoCtx.Site | $spoSite=$spoCtx.Web

            $spoSite=$spoCtx.Site

            # todo: change scope: [Microsoft.SharePoint.Client.FeatureDefinitionScope]::None | Farm | Site | Web

            # https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.featuredefinitionscope.aspx?f=255&MSPPError=-2147217396

            $spoSite.Features.Add($sFeatureGuid, $true, [Microsoft.SharePoint.Client.FeatureDefinitionScope]::None)

            #############################################

            $spoCtx.ExecuteQuery()

            $spoCtx.Dispose()
        }
        catch [System.Exception]
        {
          write-host -f red $_.Exception.ToString()   
        }    
    }

    #Required Parameters

    $sSiteColUrl = "https://tenant.sharepoint.com/sites/SharePointMigration/"

    $sUserName = "liakathali.mohammed@doman.com"

    $sFeatureGuid= "c6561405-ea03-40a9-a57f-f25472942a22"

    $sPassword = Read-Host -Prompt "Enter your password: " -AsSecureString 

    Enable-SPOFeature -sSiteColUrl $sSiteColUrl -sUserName $sUserName -sPassword $sPassword -sFeatureGuid $sFeatureGuid

Once you activate the missing features, you should be able to see the newly installed below the Custom tab for the template selection.