Programmatically Changing Retention Labels

If Purview retention labels are already applied to files across your tenant’s SharePoint sites, the need might arise to change the label that is applied. Once a label is applied to a file (through any means), it remains in place until either manually or implicitly changed using one of these methods:

  1. The default retention label is changed at the container (library or folder) level. All items within the container that have inherited the original default label will automatically update to the new default label.
  2. The retention action for the label is configured to apply a different retention label at the end of the retention period.
  3. The retention action for the label is configured to run a Power Automate flow at the end of the retention period and the flow applies a different retention label.
  4. Programmatically replace the label, which is the topic of this article.

There are several reasons for needing to programmatically replace a retention label that the first three options don’t address:

  • You may need to change the retention label before it reaches the end of its retention period and it is not set as a default label on the library or folder
  • A retention label has been applied to a file with an auto-apply label policy. The conditions have changed, and you now need a different label to be applied.
  • Retention label names don’t always stay the same. Regulations change, organizations change, and business rules change and, as a result, you may need to change a retention label to reflect the new name. Unlike sensitivity labels, you cannot change a retention label name once the label’s been created. Alternatively, you must create a new retention label with the same settings and the updated name and update files with the old retention label.

This article describes how to update a retention label on files across a SharePoint site using the Microsoft Graph PowerShell SDK. I do not explain how to retrieve a SharePoint site and the document libraries within. For an example of how to navigate within a SharePoint site, refer to Create a SharePoint Online Files Report with the Graph PowerShell SDK.

What to Know Before You Start

The script can update both a standard label and record label to another standard label or record label given the required permissions. The permissions depend on whether you are updating from a standard or record label (the ‘Item is a record’ checkbox is selected in the Purview retention label configuration for a record label).

  • Permissions for updating from a standard label: Sites.Read.All, Files.ReadWrite.All
  • Permissions for updating from a record label: Sites.FullControl.All, File.ReadWrite.All (you also need to be a site collection administrator if using delegated permissions)
  • Permissions for listing the Purview retention label settings to determine if the label you are updating from is a record label: RecordsManagement.Read.All

To determine if the label you are updating to needs to be published to the new location, you must know if the retention label you are updating to is an event-based label (the retention label is configured to start retention on a custom event date).

If the new retention label is not event-based, you do not need to publish the new retention label to the SharePoint site to apply the new retention label to files.

If the new retention label is event-based, the label update will work, but you must publish the event-based retention label to the SharePoint site so you can see the Asset Id column in the file’s detail information pane. This column is used for built-in event-based retention. If you are using a custom column instead of the Asset Id column for your event-based label, you do not need to publish the label to the site.

Note: If regulatory record labels are enabled in your tenant and applied to content, they cannot be updated. This is by design.

The Script

Disclaimer: Do not use this script in production until you have determined that the code meets the needs of your organization. This script should first be validated in a non-production environment.

The script targets all files in a document library in a single SharePoint site. In a production scenario, you could read a csv file of SharePoint site URLs and document library names for locations where the retention label update is required. This would provide the flexibility of picking which document libraries you want to change the label on in case you don’t want to necessarily change the label on all files across all document libraries. This may happen if a new label is created due to a re-organization of a company where a department is now split into two and only one of the departments needs their labels updated.

The script accepts the following parameters:

param (
    [string]$siteURL,
    [string]$documentLibraryName,
    [string]$oldRetentionLabelName,
    [string]$newRetentionLabelName
)

Figure 1 shows the script running.

Practical Purview: Replacing Purview Retention Labels with PowerShell
Figure 1: Running the Update Retention Labels script

The script must know if the old retention label is a record label so it can lock any unlocked records during the update process. The Get-MgSecurityLabelRetentionLabel cmdlet retrieves all retention labels from Purview and the retainAsRecord property on the retention label’s information identifies the label as a record label. Note: This cmdlet does not support application permissions.

$RetentionLabels = Get-MgSecurityLabelRetentionLabel
$RetentionLabel = $RetentionLabels | Where-Object { $_.DisplayName -eq $oldRetentionLabelName }
$Global:IsRecordLabel = if ($RetentionLabel.BehaviorDuringRetentionPeriod -eq "retainAsRecord") {$true} else {$false}

Only when a record label is locked can it be updated to another label. Passing the isRecordLocked parameter in the retention setting to any file with a record label that is currently unlocked will lock the file.

$params = @{ retentionSettings = @{ isRecordLocked = $true }}
Update-MgDriveItemRetentionLabel -DriveId $Drive -DriveItemId $driveItemId -BodyParameter $params

If you need to remove a label applied to a file rather than updating it to another label, you can use the Remove-MgDriveItemRetentionLabel cmdlet. In this script, I pass the word CLEAR in the new retention label name parameter to signify a retention label removal.

Remove-MgDriveItemRetentionLabel -DriveId $Drive -DriveItemId $File.Id

The script is modeled after the script in the article about generating a report about files in a SharePoint document library to retrieveall files in the library as well as the generation of a csv file which this script uses to capture label updates.

 The retention label is retrieved for each file using the Get-MgDriveItemRetentionlabel cmdlet.

$RetentionlabelInfo = Get-MgDriveItemRetentionLabel -DriveId $Drive -DriveItemId $File.id

If the old retention label is applied to the file, the script updates the label with the new label name taking care to lock any unlocked record labels prior to updating.

if ($null -ne $RetentionLabelName -and $RetentionLabelName -eq $oldRetentionLabelName) {
  if ($global:IsRecordLabel -and $RetentionLabelInfo.RetentionSettings.IsRecordLocked -ne $true) {
              Lock-Record -Drive $Drive -DriveItemId $File.Id
              $lockedByScript = $true
  } else {
              $lockedByScript = $false
  }
  if ($newRetentionLabelName -eq "CLEAR") {
       Remove-MgDriveItemRetentionLabel -DriveId $Drive -DriveItemId $File.Id
  } else {
       $UpdatedLabel = Update-MgDriveItemRetentionLabel -DriveId $Drive -DriveItemId $File.Id -BodyParameter @{name = $newRetentionLabelName}
  }  
}

The Report Output

The output is a PowerShell list (shown in Figure 2). The script also exports the content of the list to a CSV file.

Practical Purview: Replacing Purview Retention Labels with PowerShell
Figure 2: Output from the Update Retention Labels script

You can download the full script from GitHub.

What This Script Doesn’t do (but Would be Good to Add)

If a retention label is applied to a folder, all unlabeled files within the folder inherit the label. This script could be updated to check if a retention label has been applied to a folder and update the label on the folder as well.

As a script input, read a CSV file of all SharePoint sites, their document libraries, the old retention label, and the new retention label.

This script does not respond to API throttling. Depending on the size of the document library and how many files will be updated in the process, you may have to adjust the script to respond to throttling by retrying the update operation after the Retry-After delay.

This script uses delegated permissions. You may want to switch to app-only permissions in a production scenario. The Get-MgSecurityLabelRetentionLabel cmdlet does not support app-only permissions so switching to app-only permissions would require a different method to retrieve all retention labels from Purview.

Non-Technical Considerations

Consider these potential impacts not addressed in the script:

  • If any file being updated is currently under a disposition review, you may not want to update the label due to unknown downstream effects
  • If an event has already been triggered for a file that has an event-based retention label applied, you may not want to update the label since the retention event has already started

Closing Thoughts

There is a change in development in the Microsoft 365 Roadmap (Bulk replacement or removal of a retention label – Feature Id 392456) with an estimated Preview available in July 2025. Based on the description, it can perform the action of replacing/removing a retention label across the entire tenant or targeted to specific content using KQL and static or adaptive scopes. This is welcome news for organizations needing this capability.

About the Author

Joanne Klein

Joanne is an independent Microsoft 365 consultant, a 4-time Microsoft MVP in Office Apps & Services, and an Advanced Compliance specialist in the Microsoft suite of tools. Joanne works with her customers on planning and implementing information protection and governance controls across their Microsoft 365 environments to address the unique challenges of the modern workplace. She’s a firm believer that it’s not all about technology. Joanne also blogs about these areas with a focus on how to secure, protect, and govern information assets while minimizing end-user impact.

Comments

  1. Enrico Margioni

    Can you clarify, if I am using an Label only retention policy, and when I look up an account I see that label applied to that account why in OneDrive do i not see the label? When I use Explorer in purview I do see the Retention label. what am i missing? If I have a label policy that is just labeling and I want to apply another label to replace existing do i have to go into the policy and replace the label since I read an Auto apply will not override?

    1. Avatar photo
      Tony Redmond

      You mean a label publishing policy? That’s the vehicle used to make retention labels available in different locations like OneDrive and Outlook. The locations included in the policy will see the labels once the distribution process finishes and clients pick up the labels.

      1. Enrico Margioni

        Thanks Tony, yes auto apply Label policies i can see in Content explorer 11 items that match content of teams recording in my recordings folder in OneDrive, but when i look at details of the file i do not see the policy name in the details

      2. Enrico Margioni

        Ok, maybe your good luck , now I am seeing, How do i prevent end users from changing this label? label is based on content matching query (ProgID:Media OR ProgID:Meeting) I then after end usres are advised of the labeling then apply a 90 day deletion policy based on the same (ProgID:Media OR ProgID:Meeting) from creation date

    2. Joanne Klein

      In addition to what Tony said, you cannot override an existing retention label with an auto-apply label policy once it has been applied to a file (even if you replace the label in the label policy). Once you replace the label in the auto-apply label policy, only unlabeled files meeting your auto-apply condition will have the replacement label applied.

      1. Enrico Margioni

        Hello, thanks so just want to prevent users from Changing the Auto Apply. If current label is just label and i want to in 90 days change to delete, i cant do this?

        1. Joanne Klein

          This requires a setting on the original retention label configuration by selecting the ‘Change the label’ option in the ‘Choose what happens after the period’ setting (unfortunately, once you create the label, this setting can’t be changed).

          For example, if the original label is called ‘Label 1’ and the label to change it to is ‘Label 2’, then ‘Label 1’ would need to be configured with the ‘Change the label’ option I described above. You would then select ‘Label 2’ as the replacement label.

          As for your comment about not wanting users to change the auto-applied label, there’s no bullet-proof way of doing this. If ‘Label 1’ is a record retention label and not a regular retention label, then a site owner is the only one that can change/remove the label which mitigates the risk to a degree.

          1. Enrico Margioni

            Thanks! If have a manual label along with the Auto Apply with marked as Record , I am trying to confirm of the Auto apply will remove/overwrite manual tag or will the Manul tag be respected. TO note not using manual tags just trying to understand if need to add if it will allow users to set a tag and “stop” an Auto apply?

        2. Joanne Klein

          Hi Enrico (for some reason I can’t reply to your last question so putting my response on this one). Once a retention label is on an item from a manual application, an auto-apply label policy will NEVER overwrite the retention label.

          1. Enrico Margioni

            Thanks Joanne, is there a way in powershell to easily query a Label Policy to see the status, looking for some way to see if a label is being applied without going into purview and then go into into explorer..

  2. Erica Toelle

    Please do not use the undocumented Compliance tag API – it is definitely not supported, and it is unreliable. We removed it from the documentation on purpose. It may look like it’s working, but sometimes it won’t trigger retention or deletion activities correctly. The method Joanne describes is the only way we want people to update retention labels please and the only supported method currently. This is clear in our documentation.

    1. Leighroyyyyy

      Good to know, though there isn’t really an alternative that I’m aware of if retention is based on when the tag was applied. The available options in a tenant migration scenario are very limited. Feature request?

  3. Leighroyyyyy

    Something I was playing with the other day was manually setting the time that a retention tag was applied to a file (in the case where a retention tag is set to retain/delete for a period of time starting when the tag was applied). There’s an undocumented SPO API feature which allows for this:
    POST https://m365x01234567sharepoint.com/sites/SalesAndMarketing/_api/web/lists(guid'43ac866a-fc3e-40d0-9cf9-38d5c117a777‘)/items(8)/SetComplianceTagWithMetalnfo()
    Authorization: Bearer xxxxxxxxxx
    Content-Type: application/json
    {
    “complianceTag”: “Test label”,
    “blockDelete”: false,
    “blockEdit”: false,
    “isTagSuperLock”: false,
    “isRecordUnlockedAsDefault”: true,
    “complianceTagWrittenTime”: “2015-01-15T17:40:03Z”
    }

    Seemed to work. Useful in a T2T scenario where files are part way through their retention in the source tenant.

Leave a Reply