CLI for Microsoft 365 v3.5
Tags: productivity, showdev, news, microsoft365
Published: 2021-02-04 13:48:28

We’ve just published a new version of the CLI for Microsoft 365 with new commands for working with and managing Microsoft 365 tenants and SharePoint Framework projects on any platform.

## Manage Microsoft 365 and SharePoint Framework projects on any platform

CLI for Microsoft 365 is a cross-platform CLI that allows you to manage various configuration settings of Microsoft 365 and SharePoint Framework projects no matter which operating system or shell you use.

While building solutions for Microsoft 365 expands beyond the Windows operating system, managing many of the platform settings is possible only through PowerShell on Windows. As more and more users work on non-Windows machines, it’s inconvenient for them to have to use a Windows virtual machine to configure their tenants. With the CLI for Microsoft 365, you can configure your tenant no matter which operating system you use. Additionally, using CLI for Microsoft 365, you can manage your SharePoint Framework projects.

## New version of CLI for Microsoft 365 – v3.5

Following our monthly release cadence, we’ve released a new version of the CLI for Microsoft 365 with some new capabilities. Here are a few of the most noteworthy additions.

### Create Azure AD app registrations

When you build apps on Microsoft 365, one of the very first things that you need is an Azure AD app. Azure AD app represents your app on the Microsoft cloud. In your Azure AD app you configure what kind of app it is (desktop or web app), how users can authenticate (or if your app is an automated process and doesn't require user context at all) and which permissions your app requires in Microsoft 365 to work.

In this version of CLI for Microsoft 365, we've introduced a new command that simplifies creating Azure AD app registrations to a single line of code.

To create an Azure AD app for a deamon app with specified Microsoft Graph permissions, you'd execute:

```sh
m365 aad app add --name 'My AAD app' --withSecret --apisApplication 'https://graph.microsoft.com/Group.ReadWrite.All,https://graph.microsoft.com/Directory.Read.All'
```

To create an Azure AD app for a single page app, you'd run:

```sh
m365 aad app add --name 'My AAD app' --platform spa --redirectUris 'https://myspa.azurewebsites.net,http://localhost:8080' --apisDelegated 'https://graph.microsoft.com/Calendars.Read,https://graph.microsoft.com/Directory.Read.All' --implicitFlow
```

To create an Azure AD app that exposes an API, you'd execute:

```sh
m365 aad app add --name 'My AAD app' --uri api://caf406b91cd4.ngrok.io/_appId_ --scopeName access_as_user --scopeAdminConsentDescription 'Access as a user' --scopeAdminConsentDisplayName 'Access as a user' --scopeConsentBy adminsAndUsers
```

We believe that this command will help you script creating Azure AD apps in your solutions and more easily share the app configuration within your team or with your customers. For the full list of the capabilities, see the [docs of the `aad app add` command](https://pnp.github.io/cli-microsoft365/cmd/aad/app/app-add/).

### Convert files to PDF

One of the common requirements when working with documents, is to have them converted to PDF, whether for external sharing or archiving. Nowadays Office clients natively support saving files to PDF, but if you need to bulk-convert multiple files to PDF, you might be looking for a different solution.

In this version of CLI for Microsoft 365, we've introduced the ability to convert files to PDF using Microsoft Graph. Using CLI you can convert both local files as well as files that you have already stored in SharePoint or One Drive for Business.

To convert a local file to PDF, execute:

```sh
m365 file convert pdf --sourceFile file.docx --targetFile file.pdf
```

To convert a file stored in SharePoint to PDF, execute:

```sh
m365 file convert pdf --sourceFile "https://contoso.sharepoint.com/Shared Documents/file.docx" --targetFile "https://contoso.sharepoint.com/Shared Documents/file.pdf"
```

You can also mix and match source and targets and convert a local file to PDF and have the PDF stored in a document library or the other way around.

For more information and examples, see the [command's documentation](https://pnp.github.io/cli-microsoft365/cmd/file/convert/convert-pdf/).

### Send adaptive cards

When automating your work, you often need a notification when a job has completed or something requires your attention. In the past, using CLI for Microsoft 365 you could easily [send an email](https://pnp.github.io/cli-microsoft365/cmd/outlook/mail/mail-send/). In this version, we've introduced the ability to send adaptive cards, which are more convenient for carrying structured data.

To quickly send an adaptive card with just the title, execute:

```sh
m365 adaptivecard send --url https://contoso.webhook.office.com/webhookb2/892e8ed3-997c-4b6e-8f8a-7f32728a8a87@f7322380-f203-42ff-93e8-66e266f6d2e4/IncomingWebhook/fcc6565ec7a944928bd43d6fc193b258/4f0482d4-b147-4f67-8a61-11f0a5019547 --title "CLI for Microsoft 365 v3.5"
```

You can also include more information, like title, description, image and a URL:

```sh
m365 adaptivecard send --url https://contoso.webhook.office.com/webhookb2/892e8ed3-997c-4b6e-8f8a-7f32728a8a87@f7322380-f203-42ff-93e8-66e266f6d2e4/IncomingWebhook/fcc6565ec7a944928bd43d6fc193b258/4f0482d4-b147-4f67-8a61-11f0a5019547 --title "CLI for Microsoft 365 v3.5" --description "New release of CLI for Microsoft 365" --imageUrl "https://contoso.com/image.gif" --actionUrl "https://aka.ms/cli-m365"
```

If you need, you can specify additional information as well:

```sh
m365 adaptivecard send --url https://contoso.webhook.office.com/webhookb2/892e8ed3-997c-4b6e-8f8a-7f32728a8a87@f7322380-f203-42ff-93e8-66e266f6d2e4/IncomingWebhook/fcc6565ec7a944928bd43d6fc193b258/4f0482d4-b147-4f67-8a61-11f0a5019547 --title "CLI for Microsoft 365 v3.5" --description "New release of CLI for Microsoft 365" --actionUrl "https://aka.ms/cli-m365" --Version "v3.5.0" --ReleaseNotes "https://pnp.github.io/cli-microsoft365/about/release-notes/#v350"
```

Next to sending predefined adaptive cards, you can also send your own cards:

```sh
m365 adaptivecard send --url https://contoso.webhook.office.com/webhookb2/892e8ed3-997c-4b6e-8f8a-7f32728a8a87@f7322380-f203-42ff-93e8-66e266f6d2e4/IncomingWebhook/fcc6565ec7a944928bd43d6fc193b258/4f0482d4-b147-4f67-8a61-11f0a5019547 --card '{"type":"AdaptiveCard","body":[{"type":"TextBlock","size":"Medium","weight":"Bolder","text":"CLI for Microsoft 365 v3.5"},{"type":"TextBlock","text":"New release of CLI for Microsoft 365","wrap":true}],"actions":[{"type":"Action.OpenUrl","title":"View","url":"https://aka.ms/cli-m365"}],"$schema":"http://adaptivecards.io/schemas/adaptive-card.json","version":"1.2"}'
```

For the full list of what's possible, see the [command's documentation](https://pnp.github.io/cli-microsoft365/cmd/adaptivecard/adaptivecard-send/). Before you can send adaptive cards to Microsoft Teams, you will need to [configure an incoming webhook](https://docs.microsoft.com/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook?WT.mc_id=m365-13917-wmastyka).

### Get Microsoft 365 audit log

If you need to keep track of what's happening in your Microsoft 365 tenant, you will find the [audit log](https://docs.microsoft.com/microsoft-365/compliance/search-the-audit-log-in-security-and-compliance?view=o365-worldwide&WT.mc_id=m365-13917-wmastyka) invaluable. It contains useful information about the different services on Microsoft 365 that you can use to gauge activity and governance.

In this version of CLI for Microsoft 365, we've introduced the support for retrieving audit log.

To retrieve audit log for Exchange, execute:

```sh
m365 tenant auditlog report --contentType "Exchange"
```

To get audit log for SharePoint for the specified time span, execute:

```sh
m365 tenant auditlog report --contentType "SharePoint" --startTime "2020-12-13T15:00:00" --endTime "2020-12-13T16:00:00"
```

Since audit logs are available for a limited amount of time, you should consider implementing retrieving them as a part of a larger process that will also process and store them so that you can report on the particular activities over longer period of times.

For the list of supported services and capabilities, see the [command's documentation](https://pnp.github.io/cli-microsoft365/cmd/tenant/auditlog/auditlog-report/).

### List deleted Office 365 groups

For a while now [Office 365 groups](https://docs.microsoft.com/microsoft-365/admin/create-groups/office-365-groups?view=o365-worldwide&WT.mc_id=m365-13917-wmastyka) have been the foundation of many features in Microsoft 365. As you work with them, it's inevitable, that at some point you will need to clean them up.

In this version of CLI for Microsoft 365, we've introduced support for retrieving deleted Office 365 groups.

To get the list of all deleted groups, execute:

```sh
m365 aad o365group recyclebinitem list
```

The command also supports filtering groups by display- and nickname to help you quickly find the groups you're interested in.

For the full list of capabilities, see the [`aad o365group recyclebinitem list` command's documentation](https://pnp.github.io/cli-microsoft365/cmd/aad/o365group/o365group-recyclebinitem-list/).

### Resubmit flow run

[Power Automate flows](https://flow.microsoft.com/?WT.mc_id=m365-13917-wmastyka) are a great way for users and teams to automate tedious works. With just a few configuration steps, you can create flows that connect to different systems in your organization and do in seconds what in the past took hours.

In this version of CLI for Microsoft 365 we've extended support for flows with the ability to restart specific runs. If a run failed or if it got stuck, you can easily restart it, by executing:

```sh
m365 flow run resubmit --environment Default-d87a7535-dd31-4437-bfe1-95340acd55c5 --flow 5923cb07-ce1a-4a5c-ab81-257ce820109a --name 08586653536760200319026785874CU62
```

The ability to resubmit flows is a powerful tool in your toolbox if you want to build a monitoring solution that checks if all flows run as expected and automatically restarts them if needed.

For more information about this command and its capabilities see the [documentation](https://pnp.github.io/cli-microsoft365/cmd/flow/run/run-resubmit/).

### Reorder list view fields

Lists offer a convenient way for users to store structured data. With the recent release of the [Lists app for iOS](https://techcommunity.microsoft.com/t5/microsoft-365-blog/get-the-microsoft-lists-app-for-ios/ba-p/2072844?WT.mc_id=m365-13917-wmastyka) access to lists became even more convenient.

In this version of CLI for Microsoft 365, we've introduced support for re-ordering fields in lists. To change the place of the particular field in the list view, execute:

```sh
m365 spo list view field set --webUrl https://contoso.sharepoint.com/sites/project-x --listTitle Documents --viewTitle 'All Documents' --fieldTitle 'Custom field' --fieldPosition 1
```

For more information about the command and its capabilities, see the [documentation](https://pnp.github.io/cli-microsoft365/cmd/spo/list/list-view-field-set/).

### Get SharePoint page templates

Modern SharePoint pages are a great way to publish content in your organization. The enhanced editing experience makes it easy to create and style content and by adding web parts, you can enrich the content with media and other interactive elements. To simplify creating pages, you can create templates which others in your organization can use.

In this version of CLI for Microsoft 365, we've introduced the support for retrieving page templates. To list what templates have been created in the particular site, execute:

```sh
m365 spo page template list --webUrl https://contoso.sharepoint.com/sites/team-a
```

Regularly retrieving the list of page templates across your sites is a great way to understand how users publish content, if they use templates at all and if there is perhaps a need to standardize templates across your whole intranet.

For more information about retrieving SharePoint page templates using CLI, see the [`spo page template list` command's documentation](https://pnp.github.io/cli-microsoft365/cmd/spo/page/page-template-list/).

### Changes

We’ve continued improving CLI, building upon the changes we’ve introduced in the previous version.

#### Improved performance

When working with CLIs, the speed is paramount. You expect the tool to quickly respond to your instructions and work as quickly and efficiently as possible.

In this version of CLI for Microsoft 365, we've included a number of performance improvements that in some cases lead to 2x performance improvement! First of all, we've analyzed our code and, where possible, changed optional dependencies to be lazy-loaded. We've also introduced the `CLIMICROSOFT365_NOUPDATE` environment variable, which you can use to disable automatic checking for updates, and which can help you speed up CLI even further.

We'd encourage you to get the latest version of CLI for Microsoft 365 and we'd love to hear how you find the improvements.

#### Added support for passing complex content from files

When automating managing Microsoft 365, in some cases you need to pass complex content, like JSON strings, to CLI commands. Depending on which shell you use CLI with, you need to properly escape the string so that your shell knows what to pass to the CLI. This is very inconvenient to say the least.

In this version of CLI for Microsoft 365, we followed the approach used by [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli?WT.mc_id=m365-13917-wmastyka) and introduced support for using the `@` token to pass contents from files into each option.

Rather than escaping complex strings, you can now store them in a file and pass the contents of that file directly to the option:

```sh
m365 spo sitescript add --title "Contoso" --description "Contoso theme script" --content @themeScript.json
```

What follows the `@` token will be considered a path to a text file which will be read and which contents will be passed into the specific option as if you provided them inline.

We hope this improvement will save you precious time and trouble when dealing with complex strings.

#### Improved SharePoint page commands

Recently, Valo Intranet released [Doctor](https://github.com/ValoIntranet/doctor) - the static site generator for SharePoint. Doctor is a great tool if you want to combine the ease of editing with Markdown with rich publishing and search capabilities of SharePoint.

What's also great about Doctor is that it's powered by CLI for Microsoft 365. In this version of CLI for Microsoft 365, we include [several improvements and additions to SharePoint page commands](https://pnp.github.io/cli-microsoft365/about/release-notes/#changes) that we received from the team behind Doctor.

### Sample scripts

CLI for Microsoft 365 is a great tool both for quick adjustments to the configuration of your Microsoft 365 tenant as well as automating more complex tasks. Because CLI for Microsoft 365 is cross-platform you can use it on any OS and in any shell. To help you get started using the CLI for Microsoft 365 for automation scenarios, we started gathering some sample scripts.

If you have any scripts that you use frequently, please share them with us so that we can learn more about the common automation scenarios.

#### Empty tenant recycle bin

_Your deleted modern SharePoint sites are not going to disappear from the UI before they have been removed from the tenant recycle bin. You can either wait for three months, delete them manually via the SharePoint admin center, or run the CLI for Microsoft 365 script below._

Michaël Maillot contributed a sample script, originally designed by [Laura Kokkarinen](https://laurakokkarinen.com/does-it-spark-joy-powershell-scripts-for-keeping-your-development-environment-tidy-and-spotless/#empty-the-tenant-recycle-bin), to [empty the tenant recycle bin](https://pnp.github.io/cli-microsoft365/sample-scripts/spo/empty-tenant-recyclebin/).

#### Export all flows

_When was the last time you backed up all the Flows in your environment?_

_By combining the CLI for Microsoft 365 and PowerShell we can make this task easy and repeatable._

_This script will get all Flows in your default environment and export them as both a ZIP file for importing back into Power Automate and as a JSON file for importing into Azure as an Azure Logic App._

Garry Trinder contributed a sample scripts that helps you to quickly [export all Power Automate flows in your environment](https://pnp.github.io/cli-microsoft365/sample-scripts/flow/export-all-flows-in-environment/).

#### List application customizers

If you need to regularly report on customization in your tenant, this script is for you.

Rabia Williams contributed a script that allows you to quickly [get all application customizers across all sites in your tenant](https://pnp.github.io/cli-microsoft365/sample-scripts/spo/list-all-application-customizers/).

## Contributors

This release wouldn't be possible without the help of (in alphabetical order) [Aakash Bhardwaj](https://github.com/aakashbhardwaj619), [Patrick Lamber](https://github.com/plamber), [Michaël Maillot](https://github.com/michaelmaillot), [Waldek Mastykarz](https://github.com/waldekmastykarz), [Arjun U Menon](https://github.com/arjunumenon), [Abderahman Moujahid](https://github.com/Abderahman88), [Nanddeep Nachan](https://github.com/nanddeepn), [Douglas Romão](https://github.com/douglasromao), [Albert-Jan Schot](https://github.com/appieschot), [Kislay Sinha](https://github.com/sinhakislay), [Elio Struyf](https://github.com/estruyf), [Garry Trinder](https://github.com/garrytrinder/) and [Rabia Williams](https://github.com/rabwill). Thank you all for the time you chose to spend on the CLI for Microsoft 365 and your help to advance it!

## Work in progress

Here are some things that we’re currently working on.

### More commands, what else

Microsoft 365 is evolving and new capabilities are being released every day. With CLI for Microsoft 365, we aim to help you manage your tenant on any platform in a consistent way, no matter which part of Microsoft 365 you interact with. While we keep adding new commands to CLI for Microsoft 365 each release, we still barely scratched the surface with what’s possible in Microsoft 365. In the upcoming versions of the CLI for Microsoft, you can expect us to add more commands across the different workloads in Microsoft 365.

### Browser-based auth

Before you can use CLI for Microsoft 365, you need to authenticate either with your user account or as an app, if you use CLI in an automated process. While we support a number of [authentication methods](https://pnp.github.io/cli-microsoft365/cmd/login/#options), we recently discovered, that neither of them works when organizations have conditional access policies enabled.

We've been doing some work recently on introducing a new authentication method that we'll release in preview in the next version of CLI for Microsoft 365. We'd appreciate it if you could give it a try!

### Script examples

In every release of the CLI for Microsoft 365, we introduce new commands for managing Microsoft 365. With over 350 commands across the different Microsoft 365 services, the CLI for Microsoft 365 has become a powerful tool, not just for managing your tenant but also for automating your daily work.

We’d love to show you how you can use the CLI for Microsoft 365 to build automation scripts in PowerShell Core and Bash. If you have any scripts using SPO or PnP PowerShell that you use frequently, please [share](https://github.com/pnp/cli-microsoft365/issues) them with us so that we can learn more about the common automation scenarios.

### `ensure` commands

Currently, CLI for Microsoft 365 has dedicated commands for retrieving, creating and updating resources. If you were to create a script that ensures a specific configuration, for each resource you’d need to see if it exists, create it if it doesn’t or update it if it does.

We’re thinking about simplifying this scenario by introducing commands with a new verb named ensure. For example, to ensure that a particular site collection exists, instead of executing a combination of spo site list/spo site get, spo site add and spo site set, you’d execute spo site ensure with the necessary parameters which would automatically verify if the particular site exists and matches your configuration. If the site doesn’t exist, it would create it. If it does, the command would check if the properties you specified match the retrieved site and update them if necessary.

It's taken us a bit longer than we originally anticipated, but in the next version you can expect a preview of the `spo site ensure` command. We'd love you to give it a try and tell us what you think and if it's something we should implement for other commands in the CLI as well.

## Try it today

Get the latest release of the CLI for Microsoft 365 from npm by executing in the command line:

```sh
npm i -g @pnp/cli-microsoft365
```

Alternatively, you can get the latest release from Docker by executing in the command line:

```sh
docker run --rm -it m365pnp/cli-microsoft365:latest
```

If you need more help getting started or want more details about the commands, the architecture or the project, go to [aka.ms/cli-m365](https://aka.ms/cli-m365).

If you see any room for improvement, please, don’t hesitate to reach out to us either on [GitHub](https://github.com/pnp/office365-cli/discussions) or [twitter](https://twitter.com/climicrosoft365).

![](https://telemetry.sharepointpnp.com/m365dev-blog/cli-microsoft-365-3-5)