Try out Microsoft Project online

Take any plan
Trial or manage trial
remember to assign licenses

Make sure you see Project on the apps

If you want to install Microsoft Project on your machine, open this link:

This option is only available on

Check product information

Excel REST API in SharePoint Online to PowerBI

Let’s says that you have an excel file located in a SharePoint library, and you know where to get data like this, and you want to display them in Power BI:


Yes, PowerBI can get data from an excel file, but how can we do that for excel online? Luckily, there are some example URL from excel services that we can use to fetch data from Excel:

For PowerBI, Odata maybe the best one to selected

1. Get data from web (past odata link to the URL)


2. Sign in by your organization account


3. Make sure you have data in Power Query Editor


Like this


Silent Sign In on SharePoint hosted app

This is for you to embed sharepoint hosted app to your main web with silent login:

Let’s say your app start page is like this: Intranet&SPAppWebUrl=

Then you need to sign-in from your app

then sign-in from your main web

you should encode the redirect_uri to be able to use it in your iframe.

See more here:



Wildcard SSL for SP and high-trust-certificate

NOTE: The certificate for  high trust does not support CNG enabled. Have to create with a legacy option.

I. Follow this to create a new certificate using for SSL:


$cert = New-SelfSignedCertificate -DnsName “*” -CertStoreLocation “cert:\LocalMachine\My”

Then, go to iss web application -> bindings -> edit -> https -> SSL certificate: * -> host name: -> port 443

launch the web application, on address bar, click to install the certificate to the computer

II. Follow this to create a new certificate for SP high trusted app:


  1. Create a self-sign-certificate
  2. Export to pfx
  3. Export to cer
  4. Open MMC, install certificate to “Trusted Root Certificate Authority” and “Personal”
  5. On Personal, right click to the certificate -> All Tasks -> Manage Private Keys…-> Add user in your wep application pool to here
  6. Share certificate folder to everyone
  7. ……………………
  8. New-SPTrustedRootAuthority (remove first if already existed)
  9. New-SPTrustedSecurityTokenIssuer (remove first if already existed)
  10. AllowOAuthOverHttp
  11. Update OnPrem.config for all web applications
  12. IIS reset all


Get User Profile Properties with REST API

Thanks Vardhaman Deshpande for this tips:

1) Get all properties of current user:


2) Get single property of current user:


3) Get Multiple Properties for the current user:


4) Get all properties of Specific User:

For Office 365/SharePoint Online:

For SharePoint 2013 On-Premises:

5) Get Specific UserProfile Property of Specific User:

For Office 365/SharePoint Online:

For SharePoint 2013 On-Premises:

6) Get Multiple UserProfile Properties for Specific User:


Script to activate SharePoint feature on all site collection – Combine PnP and CSOM scripts

The prerequisite for this script is you need to be global admin on your tenant or you you have app installed with full permission on tenant scope

Let’s assume that your app have full permission on tenant scope, and you know the client id/client secret of your app

1. If your powersell script is not support for the execution policy, add this to your powershell windows first:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

2. Import SharePointPnPPowerShellOnline and Microsoft.Online.SharePoint.Powershell

Import-Module SharePointPnPPowerShellOnline -Scope “Local”
Import-Module Microsoft.Online.SharePoint.Powershell

Add-Type -Path “$path to client dlls\Microsoft.SharePoint.Client.dll”
Add-Type -Path “$path to client dlls\Microsoft.SharePoint.Client.Runtime.dll”

3. Declare the parameters

$global:appId = “your-client-id-guid-string”
$global:appSecret = “your-client-secret”

$global:adminUrl = “”

$global:SPFeatureId = “any-sharepoint-feature-id-fbace37b4a34”;

4. Connect to admin URL to get all site collection

Connect-PnPOnline -AppId $global:appId -AppSecret $global:appSecret -Url $global:adminUrl

$adminConnection = Get-PnPConnection

$allSitecollections = Get-PnPTenantSite -Connection $adminConnection

$sitecollections = New-Object System.Collections.ArrayList

5. For each site collection, connect again and activate the feature

foreach($siteCollection in $allSitecollections)
$targetUrl = $siteCollection.Url
Connect-PnPOnline -AppId $global:appId -AppSecret $global:appSecret -Url $targetUrl
$connection = Get-PnPConnection

#Activate SPFeature
$ctx = Get-PnPContext #This is important to get client content and use in CSOM
$site = $

$Site.Features.Add($global:SPFeatureId, $true, [Microsoft.SharePoint.Client.FeatureDefinitionScope]::None) | Out-Null

Disconnect-PnPOnline -ErrorAction SilentlyContinue

That’s all!!!

Add a custom javascript file to SharePoint library using csom

var list = Ctx.Site.GetCatalog((int)ListTemplateType.MasterPageCatalog);

var rootFolder = list.RootFolder;

bool displayTemplateExists = DisplayTemplateExists(Ctx, list, ProjectStatusAll.Title);
string destFileName = rootFolder.ServerRelativeUrl + “/Display Templates/Content Web Parts/” + “Item_ProjectStatusAll.js”;
string content = ProjectStatusAll.Content;
string ctId = “0x0101002039C03B61C64EC4A04F5361F38510660500E478F12A266BD24B842D0B2128BDDAAB”;

var fields = new List<KeyValuePair<string, string>>();

fields.Add(new KeyValuePair<string, string>(“Title”, ProjectStatusAll.Title));
fields.Add(new KeyValuePair<string, string>(“TargetControlType”, ProjectStatusAll.TargetControlType));
fields.Add(new KeyValuePair<string, string>(“DisplayTemplateLevel”, ProjectStatusAll.DisplayTemplateLevel));
fields.Add(new KeyValuePair<string, string>(“TemplateHidden”, ProjectStatusAll.TemplateHidden));
fields.Add(new KeyValuePair<string, string>(“ManagedPropertyMapping”, ProjectStatusAll.ManagedPropertyMapping));

if (!displayTemplateExists)
CreateFile(Ctx, list, content, Encoding.UTF8, destFileName, ctId, fields, false);


public File CreateFile(ClientContext Ctx, List list, string content, Encoding encoding, string destFileName, string ctId, List<KeyValuePair<string, string>> fields, bool overwrite)
// Verify encoding
if (encoding == null)
throw new ArgumentNullException(“encoding”);

if (list == null)
throw new ArgumentNullException(“list”);

FileCreationInformation fileCreateInfo = new FileCreationInformation();
fileCreateInfo.Url = destFileName;
fileCreateInfo.Content = encoding.GetBytes(content);
fileCreateInfo.Overwrite = overwrite;

File createdFile = list.RootFolder.Files.Add(fileCreateInfo);

ListItem item = createdFile.ListItemAllFields;

item[“ContentTypeId”] = ctId;

foreach (var field in fields)
item[field.Key] = field.Value;


return createdFile;

PnP Tools for SharePoint Modernization scanner + GetWebLoginClientContext


$authenticationManagerSiteScope = New-Object -TypeName OfficeDevPnP.Core.AuthenticationManager




Get SharePoint site/subsites template using javascript

var siteCollections = [;

siteCollections.forEach(function (site) {
var webCollection = null;
function getWebTemplate() {
var context = new SP.ClientContext(site);
//var context = SP.ClientContext.get_current();
var web = context.get_web();
function () {
var webTemplate = web.get_webTemplate();
var configuration = web.get_configuration();

var templateName = webTemplate + “#” + configuration;
var isTeamSite = templateName === “STS#0”;

console.log(site + “,” + templateName + “,,” + (isTeamSite? “Classic Team Site”: “”));

url: site + “/_api/web/webs/?$select=title,ServerRelativeUrl,Created,webTemplate,configuration”,
method: “GET”,
headers: {
“Accept”: “application/json; odata=verbose”
success: function (data) {
$.each(data.d.results, function (index, item) {
templateName = item.WebTemplate + “#” + (item.Configuration + 1);
isTeamSite = templateName === “STS#0”;

console.log(site + item.ServerRelativeUrl + “,” + templateName + “,,” + (isTeamSite ? “Classic Team Site” : “”));
error: function (data) {
//console.log(site + “,,Unable to get sub sites”);

function (sender, args) {
//console.log(site + “,,Unable to check the site template”);