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).
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).
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.
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!