Microsoft 365 Archive is a great new feature that allows organisations to archive inactive files directly in SharePoint document libraries – moving them to a lower-cost cold storage tier without losing discoverability or compliance coverage. Until recently, M365 Archive only supported archiving at the site level – meaning you had to archive an entire site or nothing at all. The file-level archiving public preview changes that, allowing you to archive individual files within an active site – a much more practical option for most organisations. I’ve been exploring it in my lab tenant and was very impressed with how well it integrates with the SharePoint experience. Today I will demonstrate how to automate SharePoint file archive operations – covering both Archive and UnArchive using the SharePoint REST API with Power Automate and PnP PowerShell. BIG WARNING – the REST endpoints I’m using are undocumented and unsupported, so treat this as a proof of concept rather than production-ready guidance. I’ll cover this in full detail in the API section below.

This opens up a wealth of automation possibilities – programmatically archiving files based on business logic in Power Automate, Logic Apps, or any tool capable of making a REST API call. Build conditional archiving workflows with approvals, notifications, scheduled runs, audit reporting and more.

Some Ideas

  • Build a scheduled flow that archives all files in a library that haven’t been modified in over 12 months, reducing storage costs automatically.
  • Create an approval-based archive process: a manager requests a file be archived, an approval is sent, and on approval the archive REST call fires.
  • Restore (UnArchive) files on demand – a user submits a form with a document ID and the flow rehydrates it back to full-fidelity storage.
  • Combine with SharePoint document library rules or a Power Automate scheduled trigger to keep archive policies consistent across multiple sites/libraries.

What is M365 File Archive?

Microsoft 365 Archive moves inactive SharePoint files into a cold storage tier at a fraction of the cost (~$0.05/GB vs $0.20/GB), while keeping them searchable and compliant. One key thing to note if you’re building automations around it: reactivation is instant within 7 days of archiving, but can take up to 24 hours after that – so plan accordingly if your flow or script needs to read a file back immediately after unarchiving. There are also limitations worth knowing about, including unsupported app types and file types in preview. For a full overview of pricing, limitations, and how the feature works, see the Microsoft Learn docs, the Orchestry pricing explainer, and the Orchestry IT admin guide.

There are two hidden system fields on each list item that expose the archive state. These are not available in SharePoint views out of the box – you can’t add them as columns through the normal UI. It is technically possible to force-add them and set view filtering by archive status via PowerShell, but it’s hacky – the moment a user edits the view through the browser, the filtering settings are lost. So for any serious reporting or auditing of archive status, querying programmatically via the REST API or PnP PowerShell is the reliable approach, which is exactly what both methods below demonstrate:

ColumnDescription
_FileArchiveStatusStatus of the file e.g. Archived
_FileArchiveTimeLastModifiedTimestamp of the last archive state change

Built for extensibility – Microsoft 365 Archive also includes support for Microsoft Graph APIs or PnP PowerShell’s Set-PnPFileArchiveState for integrating archive into custom workflows. In this post I’ll show the SharePoint REST approach via Power Automate and PnP PowerShell, which requires no additional tooling beyond what you likely already have.


The API Calls

⚠️ IMPORTANT – Undocumented & Unsupported Endpoints

The SharePoint REST endpoints used below for file-level Archive and UnArchive are not officially documented by Microsoft. I discovered them by analysing network calls in the Edge developer toolbar – the same approach I used when I first explored the Document Translation API. Because these endpoints are undocumented, they are unsupported – Microsoft could change, rename, or remove them at any time without notice, particularly as the feature moves from public preview toward general availability. Use these in production at your own risk, and keep a close eye on any Microsoft 365 Archive release notes.

If you want a supported, documented path today, use the Microsoft Graph APIs for Microsoft 365 Archive instead. That said – as a proof of concept and for lab/dev use, these REST endpoints work great right now!

With that caveat firmly in place, here are the two endpoints. Both are simple POST calls with no request body required – just the correct content-type headers.

Archive a File

POST /_api/Lists('<ListId>')/GetItemById(<ItemId>)/Archive

UnArchive a File

POST /_api/Lists('<ListId>')/GetItemById(<ItemId>)/Unarchive

Request Headers

HeaderValue
Acceptapplication/json;odata=verbose
Content-Typeapplication/json;odata=verbose

Note: The List ID must be a GUID (not the list name) for these endpoints to work correctly.


SharePoint File Archive with Power Automate

I will now show how to achieve Archive/UnArchive operations using Power Automate and the Send an HTTP request to SharePoint action. No premium connectors are required – this works on standard licensing.

The templated Flow is available to download here (link to your GitHub). Import it into your Power Automate environment and you’re ready to go!

Power Automate run flow panel for SharePoint File Archive showing four input fields: SiteUrl, Library Name, ID, and Archive/UnArchive dropdown

Flow Overview

The Flow is designed to be manually triggered. All four inputs are collected at trigger time – just run the Flow, fill in the prompt, and go. No need to edit the Flow itself when using it across different sites or libraries.

When a user runs the Flow they are prompted for four inputs:

InputTypeDescription
SiteUrlTextYour SharePoint site URL e.g. https://tenantname.sharepoint.com/sites/SiteName
Library NameTextThe document library name e.g. Archive
IDNumberThe SharePoint document library item ID of the file to process
Archive/UnArchiveChoiceDropdown – select either Archive or UnArchive

The Archive/UnArchive field is a dropdown choice (enum) with exactly two options – so there’s no risk of a typo causing the REST call to fail.

Flow Steps

The Flow follows this sequence:

  1. Trigger – Manual button trigger collecting all four inputs above from the user.
  2. Send an HTTP request to SharePoint – Get List – Calls /_api/web/lists/GetByTitle('<LibraryName>') using the trigger inputs directly to retrieve the List GUID. This is required because the Archive/UnArchive endpoint needs the List ID, not the list title.
  3. Send an HTTP request to SharePoint – Archive or UnArchive File – Makes the POST call to the archive endpoint, dynamically building the URL using the List GUID from step 2 and the item ID and action from the trigger inputs.

Key Action: Archive or UnArchive HTTP Request

The final HTTP action in the Flow is where the magic happens. Here is how it is configured:

PropertyValue
Site Address@triggerBody()?['text_1']
MethodPOST
Uri_api/Lists('@{body('Send_an_HTTP_request_to_SharePoint_-_Get_List')?['d']?['Id']}')/GetItemById(@{triggerBody()?['number_1']})/@{triggerBody()?['text']}
Headers – content-typeapplication/json;odata=verbose

The Uri dynamically inserts:

  • The List GUID retrieved from the Get List step
  • The Item ID (number_1) provided by the user at trigger time
  • The action (Archive or UnArchive) selected by the user at trigger time (text)

This means one Flow handles both operations cleanly – no conditions, no parallel branches needed.


SharePoint File Archive with PowerShell

I will now show how the same File Archive and UnArchive operations can be automated using PnP PowerShell.

Why not use Set-PnPFileArchiveState? PnP PowerShell does include a Set-PnPFileArchiveState cmdlet, but it routes through the Microsoft Graph beta archive APIs and requires delegated Graph permissions (Files.ReadWrite, Files.Read.All etc.). My approach using Invoke-PnPSPRestMethod calls the same underlying SharePoint REST endpoints that the UI uses – so it works with standard SharePoint permissions and no additional Graph consent is needed. Simpler to set up, and no dependency on a beta API.

Script – List Archive Status

$listname = "Archive"
Connect-PnPOnline -Url "https://leonarmstonmvp.sharepoint.com/sites/syntex"
$site = Get-PnPSite -Includes Id
$list = Get-PnPList -Identity $listname
$items = Get-PnPListItem -List $list
foreach ($item in $items) 
{
    Write-Host "Item ID: $($item.Id), Title: $($item['FileLeafRef']), Archive Status: $($item['_FileArchiveStatus']), Last Modified: $($item['_FileArchiveTimeLastModified'])"
}

Run this first to get a full picture of your library – it prints the item ID, filename, and current archive status for every file. Note the item ID of the file you want to action, then use one of the standalone snippets below. The _FileArchiveStatus column will return Archived once the file has been moved to cold storage.

Standalone Snippets

Fill in the three variables at the top – your site URL, library name, and the item ID of the file you want to action. You can find the item ID by selecting the file in SharePoint and checking the URL, or by running the listing script above.

Want to action multiple files at once? These snippets target a single item ID, but it’s straightforward to extend them into a loop – for example, feed in an array of IDs, or pipe the output of the listing script through a filter (e.g. only items where _FileArchiveStatus is empty and Last Modified is older than a certain date) and call the REST method for each one. The full script structure above gives you the loop scaffold to work from.

<pre class="wp-block-syntaxhighlighter-code"># --- Fill these in ---
$siteUrl  = "https://yourtenant.sharepoint.com/sites/yoursite"  # Your SharePoint site URL
$listName = "Documents"                                          # Your document library name
$itemId   = 42                                                   # The ID of the file to archive
# --- Connect and get required IDs ---
Connect-PnPOnline -Url $siteUrl
$site = Get-PnPSite -Includes Id
$list = Get-PnPList -Identity $listName
# --- Archive the item ---
Invoke-PnPSPRestMethod -Method POST <code>
    -Url "$($site.Url)/_api/Lists('$($list.Id.Guid)')/GetItemById($itemId)/Archive" </code>
    -ContentType "application/json;odata=verbose" <code>
    -Accept "application/json;odata=verbose"
</pre>
<pre class="wp-block-syntaxhighlighter-code"># --- Fill these in ---
$siteUrl  = "https://yourtenant.sharepoint.com/sites/yoursite"  # Your SharePoint site URL
$listName = "Documents"                                          # Your document library name
$itemId   = 42                                                   # The ID of the file to unarchive
# --- Connect and get required IDs ---
Connect-PnPOnline -Url $siteUrl
$site = Get-PnPSite -Includes Id
$list = Get-PnPList -Identity $listName
# --- UnArchive the item ---
Invoke-PnPSPRestMethod -Method POST </code>
    -Url "$($site.Url)/_api/Lists('$($list.Id.Guid)')/GetItemById($itemId)/Unarchive" <code>
    -ContentType "application/json;odata=verbose" </code>
    -Accept "application/json;odata=verbose"
</pre>

Summary

SharePoint file archive automation – whether through Power Automate or PnP PowerShell – is a really powerful approach for lifecycle management and cost optimisation scenarios. A few lines of PowerShell or a small Flow can enforce archive policies that would otherwise require manual intervention or expensive third-party tools.

What I particularly like about this approach is the simplicity of the REST API – there’s no complex request body, just a well-formed POST to the right endpoint. Combine this with scheduled triggers, SharePoint column values, or line-of-business system events and you have a very capable archive automation pipeline.

Do let me know in the comments if you are using M365 File Archive and especially if you’re automating it like this! Let me know if you have any questions.

This Post Has One Comment

  1. Jerry

    Hi, this is a great guide. However the template can’t be downloaded. Can you share the template again? Thank you.

Leave a Reply