May 18, 2020

Working with Office365 CLI and JSON parameters

Hi Microsoft 365 fellows,

In this post, I will give you some tips to work with Office 365 CLI commands that need some JSON as parameters.

The Office 365 CLI

If you happened to be following just a bit what's going on in the SharePoint and Microsoft 365 community, you probably already know what the Office 365 CLI is !

If you don't

The Office 365 CLI is a cross platform CLI tool running on NodeJS that allows you to perform tons of administrative (and more) tasks on your Office 365 tenant. It is an open-source and community contributed tool under the PnP umbrella. It is somehow similar to PnP PowerShell except it is cross-platform (PnP PowerShell is still not really supported cross-platform due to some underlying technical reasons...) Initially created by Waldek Mastykarz more than 2 years ago, it had then only a couple commands to achieve tasks not available on non-Windows OSes. More and more people started contributing to it (myself included for only a few commands) and the tool has now hundreds of commands ! The community really rocks !

Commands and JSON

Basically all of the commands of the CLI that return an output can return it in JSON format using the --output json parameter. It is really handy if you need to write a script that processes the result and might have conditional logic. PowerShell has the tool ConvertTo-JSON and ConvertFrom-JSON. If you are working on Linux or Mac OSX, jq can be handy as well, it allows you to manipulate JSON data. Its syntax is still a bit obscure to me but well, I'm more of a PowerShell guy... But some of the commands require JSON as the value of a parameter, And THAT might make you banging your head against the wall ! Why ?  Mainly because of double quotes mandatory in JSON that have also their own meaning in the host script language (either PowerShell or Bash). You then need to escape them for the scripting language, but hey... the value still need to be the actual JSON for the CLI to process it properly !

Commands that need JSON as parameter value

I can think of at least 3 commands that require JSON as arguments:

$ o365 spo page clientsidewebpart add $ o365 spo sitescript add $ o365 graph schemaextension add

There might be other commands as well, but I particularly know these ones (I contributed two of them :D) If you don't properly escape the quotes, you will probably get an error like :

Specified webPartProperties is not a valid JSON string. Input: {. Error: SyntaxError: Unexpected end of JSON input

Because at the first double quote, the scripting host will consider it as the end of the argument value, and in a JSON payload, there is typically a " after the first { ...

Tips to prepare JSON value parameters

Let's focus on the command to add a WebPart on a modern page (spo page clientsidewebpart add). The same tips will apply for other commands as well ! Let's say we want to deploy a WebPart and configure two of its properties from our script, a field myChoices which takes an array of strings as value, and a field description which takes a string as value. Keep in mind that we want these values might come from processed values or returned from previous commands outputs, we will hard code them here, but consider their value will only be known at execution time!

In PowerShell

We'll use a hashtable that we can easily convert to JSON format. The key thing after that is to escape properly the double quotes in the JSON and in the values themselves. Because otherwise, they would interfere with the double-quotes processing of PowerShell...

$site = "https://contoso.sharepoint.com/sites/site1"
$pageName = "AModernPage.aspx"
$webPartId = "af660fc1-c09b-4c15-b093-2b74b047286b"

$choice1 = "Choice 1"
$choice2 = "Choice 2"

# Put all the WebPart properties in a PowerShell hashtable
$webPartProps = @{
    myChoices              = @($choice1, $choice2);
    description            = 'My "Awesome" WebPart';
};

# Build JSON string from PowerShell hashtable object
$webPartPropsJson = $webPartProps | ConvertTo-Json -Compress
# Make sure to add the backticks, double the JSON double-quotes and escape double quotes in properties'values
$webPartPropsJson = '`"{0}"`' -f $webPartPropsJson.Replace('\','\\').Replace('"', '""')     

o365 spo page clientsidewebpart add -u $site -n $pageName --webPartId $webPartId --webPartProperties $webPartPropsJson

In Bash

We basically have to address the same concern in Bash, however, as far as I know, we don't have such a convenient capability as PowerShell hashtable coupled with ConvertTo-JSON. We have to somehow build the JSON "manually" making sure we are still escaping the double quotes properly. In this case we will use the standard unix printf (It reminds me awesome memories of my first steps in "real" programming with C language :) ).

#!/bin/bash
site=https://contoso.sharepoint.com/sites/site1
pageName=AModernPage.aspx
webPartId=af660fc1-c09b-4c15-b093-2b74b047286b

choice1='Choice X'
choice2='Choice Z'
description='My "Super Awesome" WebPart';
# Build the JSON including your dynamic values with printf
# For each argument that might be dynamic, we escape the double quotes " with \"
# Make sure not to ommit the surrounding back ticks and surrounding double quotes for each arguments
printf -v webPartPropsJson '`{"myChoices":["%s","%s"], "description":"%s"}`' "${choice1//\"/\\\"}" "${choice2//\"/\\\"}" "${description//\"/\\\"}"

o365 spo page clientsidewebpart add -u $site -n $pageName --webPartId $webPartId --webPartProperties $webPartPropsJson

That's it !

Yes it looks very simple ! But I can promise that if you don't know exactly how to format  and escape properly these values you might go crazy trying all sorts of combinations with quotes, double quotes, triple quotes, Backticks and so on... Now you probably know how you need to format :)

Hope you will find it useful !

Cheers

Yannick

Other posts