How to Decrypt SharePoint Online Documents Using PowerShell and the Graph API

Unlocking Protected SharePoint Documents

In my article about how to decrypt SharePoint Online documents with PowerShell, I explained how to use the Unlock-SPOSensitivityLabelEncryptedFile cmdlet to remove sensitivity labels from files. The example script uses cmdlets from the SharePoint PnP module to return a set of files from a folder in a document library for processing, and the unlock cmdlet then removes protection from any file with a sensitivity label.

The script works, but it’s not as flexible as I would like. For instance, because PnP can’t distinguish files with labels, every document in the folder is processed whether it is labelled or not. This does no harm, but it’s not something that you might want to do in the case of something like a tenant-to-tenant migration where thousands of protected documents might need to be processed.

Update May 10, 2021: The latest version of the SharePoint Online PowerShell module contains the Get-FileSensitivityLabelInfo cmdlet. This can be run to return the label status of a file, including if the label assigned to the file encrypts the file. The existence of this cmdlet removes some of the need to use the Graph to find and remove labels from protected files, but the Graph is still the fastest way to get the job done.

Using the Sites Microsoft Graph API

Which brings me to an updated version of the script (available from GitHub), which uses the Sites API from the Microsoft Graph to navigate through SharePoint Online and find labelled documents to process. Apart from being able to search for documents with sensitivity labels, a Graph API is usually the fastest way to deal with large numbers of objects.

Because we’re making Graph calls from PowerShell, we need to create a registered app in Azure AD to use as the entry point to the Graph (the same steps as outlined in this post are used). The app needs to be able to read site data, so I assigned it Sites.Read.All and Sites.ReadWrite.All permissions (Figure 1).

Setting API permissions for the Graph app
Figure 1: Setting API permissions for the Graph app

Finding Protected Documents

The script accepts two parameters: the name of the site to search (not the URL) and an optional folder. If multiple matching sites are found, the user is asked to choose which one to search (Figure 2).

Choosing a SharePoint Online site to investigate for protected documents
Figure 2: Choosing a SharePoint Online site to investigate for protected documents

Once a target site is confirmed, the script figures out if a folder is specified and if that folder exists in the chosen site. In Graph terms, we’re now dealing with drive objects. The default drive is the root folder of a document library and each folder is a different drive. To find folders, we need to find the child objects in the root, identify the right folder, find its drive identifier, and use that to find the files in the folder. All good, clean Graph fun.

The Drive API returns a maximum of 200 items at a time, so some Nextlink processing is needed to fetch the complete set of files in a folder. Each file is examined to figure out if it has a sensitivity label with protection, and if so, the display name of the label. After processing all the files, we tell the user what we’ve found and ask permission to go ahead and decrypt the files (Figure 3). If the user chooses not to proceed, the script writes details of the protected files out to a CSV file.

Reporting the protected files found in a folder in a SharePoint Online document library
Figure 3: Reporting the protected files found in a folder in a SharePoint Online document library

Decrypting Files

Files are decrypted by calling the Unlock-SPOSensitivityLabelEncryptedFile cmdlet. There’s no native Graph API call to decrypt SharePoint documents. In any case, we’re running a PowerShell script so it’s easy to call the cmdlet.

An Example to Build On

The script is an example of what’s possible with a combination of PowerShell and Graph API calls. I’m sure that the code and the functionality can be improved (feel free to suggest changes and improvements via GitHub). I’m just happy to demonstrate how things work and how including the Graph enables some extra flexibility.


Read the Office 365 for IT Pros eBook to find much more information about how sensitivity labels work – and many PowerShell examples too!

12 Replies to “How to Decrypt SharePoint Online Documents Using PowerShell and the Graph API”

  1. I’ve tried running this on a site that I know for sure has lots of encrypted files but just get the following response “No encrypted files found in Site-Name – exiting”. Any ideas?

      1. These files were originally labelled with AIP scanner does that make any difference?

      1. That’s because the script doesn’t go into subfolders. The code is written to illustrate a principle, not to handle every condition you might like it to. I would never have any time if I tried to do that… So I don’t…

  2. Love this script – shame that Microsoft haven’t got a good native way to decrypt content for tenant to tenant moves. I am running into an issue though with a test environment; the list of protected content is returned but for each item but when attempting to decrypt, see the error “Unlock-SPOSensitivityLabelEncryptedFile : Invalid URI: The format of the URI could not be determined.”. Any ideas?

    1. Have you been able to run the cmdlet interactively with PowerShell? There’s something obviously up with the URI that’s been fed into it. So I would look at the URI and figure out what PowerShell is trying to process by starting with an attempt to remove a label from a single document.

  3. This is a great article, just what I was looking for for our decryption toolbox! – Would you know of an article showing how to use PowerShell to apply a label to selected documents/folders in SPO? Cheers Danny

    1. There’s an API coming. It’s not yet available. I hope to have some information about it before the end of July. However, to set expectations, the API will be throttled and is not designed for high-scale application of labels to documents.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.