Wicked Smart Data
LearnInsightsAboutContact
Sign InLet's Build
LearnInsightsAboutContact
Sign InLet's Build
Wicked Smart Data

Intelligence, automation, and expert execution — plus an elite library of free knowledge. We turn complexity into competitive advantage.

Start a conversation

Platform

  • Learning Paths
  • Insights
  • RSS Feed

Company

  • About
  • Contact
  • Work With Us

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Wicked Smart Data. All rights reserved.

Intelligence · Automation · Advantage

All Insights
Power Automate

Automating SharePoint Document Library Version Control with Power Automate: Archiving, Restoring, and Enforcing Retention Policies Across Sites

Learn how to build a production-grade version governance system in Power Automate that automatically archives document versions, enables self-service restoration, and enforces configurable retention policies across SharePoint sites — with a complete audit trail behind every action.

⚡ Practitioner23 min readSep 19, 2026Updated Sep 27, 2026
Automating SharePoint Document Library Version Control with Power Automate: Archiving, Restoring, and Enforcing Retention Policies Across Sites
On this page
  • Introduction
  • Prerequisites
  • Understanding SharePoint Version History at the API Level
  • Building the Archive Flow: Preserving Versions Across Sites
  • Flow 1: Scheduled Version Archiver
  • Building the Restoration Flow: Self-Service Version Recovery
  • Flow 2: Version Restoration on Request
  • Enforcing Retention Policies: Pruning and Locking at Scale
  • Flow 3: Retention Policy Enforcer
  • Cross-Site Considerations and Permission Architecture
  • Instrumenting for Observability
  • Hands-On Exercise
  • Common Mistakes & Troubleshooting
  • Summary & Next Steps
  • Automating SharePoint Document Library Version Control with Power Automate: Archiving, Restoring, and Enforcing Retention Policies Across Sites

    Introduction

    Here's a scenario that plays out in organizations every week: A regulatory audit arrives, and someone asks your team to produce every version of a critical contract from the past three years — including who changed it, when, and what changed. The documents are in SharePoint. Version history is enabled. But no one ever automated what happens to old versions, which means some files have 200 minor versions bloating storage quotas, others were purged when a site owner got frustrated with the clutter, and the retention policy that Legal asked for in 2021 exists only as a PDF on a forgotten SharePoint page.

    If that scenario sounds familiar, this lesson is for you. Document version control is one of those operational concerns that feels optional right up until it isn't — and by then, the cost of getting it wrong is steep. The good news is that Power Automate gives you everything you need to build a production-grade version management system: automated archiving to a preservation library, on-demand version restoration, and enforceable retention policies that run on a schedule without anyone remembering to press a button.

    By the end of this lesson, you'll have built three interconnected flows that work together as a version governance system. You'll understand how SharePoint's versioning API works, how to move file versions across site boundaries, and how to build retention logic that's flexible enough for real compliance requirements.

    What you'll learn:

    • How SharePoint version history works at the API level and how Power Automate interacts with it via HTTP actions
    • How to build a scheduled archiving flow that copies specific document versions to a preservation library across sites
    • How to trigger a version restoration flow from a SharePoint list, giving document owners a self-service option
    • How to enforce retention policies that delete old versions or lock documents after a configurable time window
    • How to instrument your flows with logging and error handling so the system is auditable and debuggable in production

    Prerequisites

    You should be comfortable building flows in Power Automate and working with SharePoint as a data source. Specifically, you'll want to have a working grasp of:

    • SharePoint list and library actions (Get Items, Get File Properties, etc.)
    • Using HTTP with SharePoint (we'll cover the API calls in detail, but you should know what an HTTP action is)
    • Basic expressions and JSON parsing in Power Automate

    If you need to catch up on any of these, the lesson on working with conditions, loops, and variables in Power Automate is a solid refresher before proceeding.

    For your SharePoint environment, you'll need:

    • A Source Library where documents live and versioning is enabled (Major and minor versions recommended, keep at least 50 versions)
    • A Preservation Library on a separate site (or the same site) where archived versions will land
    • A Version Control Log SharePoint list for tracking actions
    • Site Collection Admin or Owner permissions on both sites
    • A Power Automate Premium license (the HTTP with SharePoint connector requires it)

    Understanding SharePoint Version History at the API Level

    Before writing a single flow action, you need to understand what you're actually working with. SharePoint's versioning system stores every saved version of a file as a separate snapshot in a hidden versions store. Each version has a version label (like 1.0, 2.0, 2.3), a timestamp, a modified-by user, and — crucially — its own download URL.

    When you use the "Get file properties" action in Power Automate, you get metadata about the current version only. To get the full version history, you need to call the SharePoint REST API directly using the Send an HTTP request to SharePoint action.

    The endpoint you'll use most is:

    GET /_api/web/GetFileByServerRelativeUrl('/sites/YourSite/LibraryName/FileName.docx')/Versions
    

    This returns a JSON array of all versions for that file. Each object in the array looks roughly like this:

    {
      "VersionLabel": "3.0",
      "Created": "2024-11-15T09:23:41Z",
      "CreatedBy": {
        "LoginName": "i:0#.f|membership|jane.doe@contoso.com",
        "Title": "Jane Doe"
      },
      "CheckInComment": "Final review edits",
      "IsCurrentVersion": false,
      "Url": "sites/ProjectDocs/Contracts/_vti_history/512/SOW_ClientA.docx"
    }
    

    The Url field is the relative path to that specific version's binary. You can construct a download URL by prepending your tenant root — something like https://contoso.sharepoint.com/ — to that value. This is how you'll extract individual versions for archiving.

    Key insight

    The IsCurrentVersion field lets you skip the live version when archiving old copies. When building retention logic, you'll always want to filter this to false before deleting anything — you never want to archive or delete the current version.

    The other important API call is for restoring a version:

    POST /_api/web/GetFileByServerRelativeUrl('/sites/YourSite/Library/File.docx')/Versions/RestoreByLabel(versionlabel='2.0')
    

    This promotes a past version to become the current version. The old "current" version doesn't disappear — it gets pushed back into version history. This is safe by default, and it's the basis for the self-service restoration flow you'll build later.


    Building the Archive Flow: Preserving Versions Across Sites

    The archiving flow runs on a schedule — daily, weekly, or triggered by a file modification event — and copies qualifying old versions from your source library to a preservation library on another site. "Qualifying" is the key word: you define the rules (age, version label pattern, document type) and the flow applies them consistently.

    Flow 1: Scheduled Version Archiver

    Trigger: Recurrence — daily at 11 PM

    Understanding when to run a scheduled flow versus an event-driven one matters here. If you triggered this on every file modification, you'd be archiving constantly and creating chaos. Nightly runs let changes accumulate, then sweep once. For more on choosing the right trigger type, see the Power Automate triggers: when to start a flow lesson.

    Step 1: Get all files modified in the last 24 hours

    Add a Get files (properties only) action pointed at your source library. Set the Filter Query to:

    Modified ge '@{addHours(utcNow(), -24)}'
    

    Warning

    The SharePoint OData filter for date comparison uses the format above, but it can behave unexpectedly if the Modified field is displayed in local time in your list view while actually stored in UTC. Always use utcNow() in your filter and verify your results in the first few test runs.

    Enable pagination if your library has more than 5,000 files. If you're not sure how pagination works with large SharePoint datasets, the lesson on handling pagination and throttling when querying large datasets in Power Automate will save you from a frustrating edge case later.

    Step 2: Loop through each file

    Add an Apply to each action using the value from step 1. Inside it, you'll build the logic for each file.

    Step 3: Get version history via HTTP

    Inside the loop, add a Send an HTTP request to SharePoint action:

    • Site Address: your source site URL
    • Method: GET
    • Uri: _api/web/GetFileByServerRelativeUrl('@{items('Apply_to_each')?['{ServerRelativeUrl}']}')/Versions
    • Headers: Accept: application/json;odata=verbose

    Parse the response body with a Parse JSON action. The schema should match the version object structure shown earlier. You can generate it by pasting a sample response into the "Generate from sample" option.

    Step 4: Filter to archivable versions

    Add a Filter array action on the parsed versions. Your filter condition:

    @{item()?['IsCurrentVersion']} is equal to false
    AND
    @{item()?['Created']} is less than @{addDays(utcNow(), -30)}
    

    This captures versions older than 30 days that aren't the current version. Adjust the day threshold to match your policy. If you're working with legal contracts, you might filter by version label pattern instead — for example, only archiving major versions (where VersionLabel ends in .0) to avoid preserving every minor autosave.

    Tip

    Build the filter logic incrementally. Start with just IsCurrentVersion = false and log the results to your Version Control Log list to see what you'd be archiving before you commit to actually moving files. This "dry run" approach saves a lot of undo work.

    Step 5: Archive each qualifying version

    Add a nested Apply to each on the filtered array. For each version:

    1. Construct the download URL:

      https://contoso.sharepoint.com/@{items('Apply_to_each_versions')?['Url']}
      
    2. Use an HTTP action (not the SharePoint one — the standard HTTP connector) with method GET and that URL to download the version's binary content. Set authentication to "Active Directory OAuth" with your tenant credentials (or use a service principal — see the integrating Power Automate with Azure Key Vault and Managed Identities guide for doing this properly in production).

    3. Use Create file action pointed at your preservation library. Set the file name to include version context:

      @{items('Apply_to_each')?['FileLeafRef']}_v@{items('Apply_to_each_versions')?['VersionLabel']}_@{formatDateTime(items('Apply_to_each_versions')?['Created'], 'yyyyMMdd')}.docx
      

      This produces names like SOW_ClientA_v2.0_20241115.docx — unambiguous and sortable.

    4. Set the file content to body('HTTP_Download_Version').

    Step 6: Log to the Version Control Log list

    After a successful archive, create a new item in your log list with:

    • File Name: original file name
    • Version: version label
    • Action: "Archived"
    • Timestamp: utcNow()
    • Source URL: the server-relative URL of the original
    • Destination: the preservation library path
    • Triggered By: "Scheduled Archiver"

    This log is your audit trail. It's also how you'll drive the restoration flow in the next section.

    Note

    Don't try to archive all versions on the first run — you could generate hundreds of HTTP calls per file and hit throttling limits immediately. Consider adding a condition that skips archiving if a log entry already exists for that version. Query your log list at the start of the loop using "Get items" with a filter on FileName and VersionLabel.


    Building the Restoration Flow: Self-Service Version Recovery

    Nobody wants to email IT to recover a document version. The restoration flow gives document owners a self-service option: they submit a request via a SharePoint list, and the flow handles the technical work of calling the restore API.

    Flow 2: Version Restoration on Request

    Trigger: When an item is created in a "Version Restore Requests" list

    Set up a simple SharePoint list called Version Restore Requests with these columns:

    • Title (use as Requester Name)
    • DocumentLibrary (Text — the library name)
    • FileName (Text — just the file name, e.g., SOW_ClientA.docx)
    • VersionLabel (Text — e.g., 2.0)
    • Justification (Multi-line text)
    • Status (Choice: Pending / Approved / Rejected / Completed)

    You could add an approval step here. If your organization requires a second pair of eyes before restoring a version, wire in an approval workflow before the actual restore action. For the base case, let's assume the requester is the document owner and has authority to restore.

    Step 1: Validate the request

    Before calling the API, confirm the version label exists in version history. Add a Send an HTTP request to SharePoint action identical to the one in the archive flow (GET Versions endpoint), then use a Filter array to check if the requested version label exists:

    @{item()?['VersionLabel']} is equal to @{triggerOutputs()?['body/VersionLabel']}
    

    Add a Condition action: if the filter array length is 0, update the request item's Status to "Rejected" and send the requester a notification explaining the version doesn't exist. Terminate the flow.

    Step 2: Call the Restore API

    If the version exists, add a Send an HTTP request to SharePoint action:

    • Method: POST
    • Uri:
      _api/web/GetFileByServerRelativeUrl('/sites/ProjectDocs/@{triggerOutputs()?['body/DocumentLibrary']}/@{triggerOutputs()?['body/FileName']}')/Versions/RestoreByLabel(versionlabel='@{triggerOutputs()?['body/VersionLabel']}')
      
    • Headers:
      Accept: application/json;odata=verbose
      X-RequestDigest: (use the form digest from a prior HTTP call to /_api/contextinfo)
      

    Warning

    The RestoreByLabel POST call requires a valid request digest token — SharePoint's CSRF protection mechanism. Before calling Restore, add another HTTP action that POSTs to /_api/contextinfo with an empty body. Parse the response to extract FormDigestValue and pass it as the X-RequestDigest header. Skipping this step causes a 403 error that's easy to misdiagnose.

    Step 3: Confirm and notify

    After the restore POST, check the response status code. A 200 means success. Update the request item's Status to "Completed" and send the requester an email or Teams notification confirming which version is now live. Log the action in your Version Control Log list just as you did in the archiving flow.

    If the status code is anything other than 200, update Status to "Failed," log the error body, and alert the flow owner. The lesson on master error handling and retry patterns in Power Automate goes deep on building this kind of resilient error path.


    Enforcing Retention Policies: Pruning and Locking at Scale

    Retention policy enforcement is where most organizations fall down. The policy exists in a document. Someone reads it occasionally. But the actual enforcement — deleting versions older than 7 years, locking documents after a certain period, moving expired content to a legal hold — is manual, which means it's inconsistent.

    You're going to automate it.

    Flow 3: Retention Policy Enforcer

    Trigger: Recurrence — weekly, Sunday at 2 AM

    You want this to run less frequently than the archiver, and at a quiet time when the throttling headroom is largest. For production scheduling considerations, see the lesson on scheduling and managing time-based flows in Power Automate.

    Design the policy as data, not code

    Instead of hardcoding retention rules in the flow, store them in a SharePoint list called Retention Policies. Columns:

    • PolicyName (Text)
    • LibraryName (Text)
    • SiteUrl (Text)
    • MaxVersionAgeDays (Number — delete versions older than this)
    • MaxVersionCount (Number — keep only this many versions per file)
    • LockAfterDays (Number — set file to read-only after this many days without modification)
    • Action (Choice: DeleteOldVersions / LockDocument / MoveToLegalHold / NotifyOwner)
    • IsActive (Yes/No)

    This gives you a policy engine that non-developers can adjust without touching the flow itself. A compliance officer can open that list and say "we need to keep versions for 2,555 days now" and change the number without a flow modification.

    Step 1: Load active policies

    At the start of the flow, use Get items on your Retention Policies list with IsActive eq 1 as the filter. Apply to each policy in the results.

    Step 2: Get all files in the target library

    For each policy, use Get files (properties only) against the library at that policy's SiteUrl and LibraryName. You may need to use the Send an HTTP request to SharePoint action here if you're targeting a site different from your flow's default connection — Power Automate's native SharePoint actions let you specify site addresses directly, which is simpler and preferred.

    Step 3: Apply MaxVersionCount enforcement

    For each file, get its version list. Sort versions by Created date descending (newest first). If the count exceeds MaxVersionCount from the policy, slice the array:

    @{skip(body('Parse_JSON_Versions')?['d']?['results'], triggerOutputs()?['body/MaxVersionCount'])}
    

    The skip() function returns everything after the first N items — in other words, the versions you want to delete. For each version in this slice, call the delete endpoint:

    DELETE /_api/web/GetFileByServerRelativeUrl('...')/Versions(@{items('Versions_to_delete')?['ID']})
    

    Note you're deleting by version ID, not label. The ID is a numeric integer in the version response object. This is important because DeleteByLabel only works with the RestoreByLabel syntax, and some SharePoint configurations are finicky about it.

    Step 4: Apply MaxVersionAgeDays enforcement

    Separately (or combined into the same version loop), filter versions where Created is older than addDays(utcNow(), mul(-1, items('Apply_to_each_Policy')?['MaxVersionAgeDays'])). Delete each one using the same DELETE endpoint.

    Key insight

    Order matters when combining MaxVersionCount and MaxVersionAgeDays. Apply the age filter first, then check the count. If you reverse it, you might delete recent versions to hit a count limit and then find the only remaining versions are old ones that should also be deleted — leaving the file with fewer versions than expected and triggering weird edge cases in subsequent runs.

    Step 5: Apply LockAfterDays

    For documents where Modified is older than LockAfterDays, you want to set the file to read-only. SharePoint doesn't have a direct "read-only" toggle via REST on individual files in the same way it does for list items, but you can achieve this by:

    1. Breaking role inheritance on the file
    2. Removing Edit permissions
    3. Keeping Read permissions

    Use these HTTP calls:

    POST /_api/web/GetFileByServerRelativeUrl('...')/ListItemAllFields/breakroleinheritance(copyRoleAssignments=true,clearSubscopes=true)
    

    Then remove the Edit role:

    POST /_api/web/GetFileByServerRelativeUrl('...')/ListItemAllFields/roleassignments/getbyprincipalid(@{UserID})/roles/deleteroledefinitions(@{EditRoleId})
    

    Getting the User ID and Role Definition ID requires additional HTTP lookup calls — GET /_api/web/currentuser for the principal and /_api/web/roledefinitions for the role IDs. This is verbose but doable. Alternatively, for a lighter-touch lock, set a custom metadata column like RetentionLocked = Yes and train your governance process to treat that flag as authoritative.

    Step 6: Log every policy action

    Every deletion, lock, and notification should generate a row in your Version Control Log with Action = "PolicyEnforced", the policy name, and the specific file and version affected. This log is non-negotiable for compliance — if someone asks why a version is gone, your log should have the answer.


    Cross-Site Considerations and Permission Architecture

    Running these flows across multiple sites introduces a permission challenge. The account or service principal running your flow needs appropriate access to every source and destination site. In production, you should be using a dedicated service account or, better, a service principal with an Azure App Registration.

    Set the service principal up with the following SharePoint permissions via the /_api/SPAppOnly/GrantAccess endpoint or through the Azure AD portal:

    • Sites.ReadWrite.All — needed for archiving and restoration
    • Sites.FullControl.All — needed for breaking role inheritance in the lock step

    Warning

    Sites.FullControl.All is a broad permission. If your security posture doesn't allow it, scope the lock enforcement to only sites where the service principal has been explicitly granted Site Owner rights. Work with your SharePoint admin to set up fine-grained permissions per site collection if needed.

    For managing credentials in flows that touch multiple sites, the guide on securing Power Automate flows in production: managing credentials, connection references, and data loss prevention policies covers exactly this situation and is worth reading in parallel.

    If you're deploying these flows across multiple environments — dev, test, prod — package them as a solution and use environment variables for site URLs, library names, and policy list paths. The ALM pipelines and solution-aware flows guide explains this pattern in detail.


    Instrumenting for Observability

    A version governance system that runs invisibly is one you'll never trust. You need to know it's running, what it's doing, and when it fails.

    Structured logging to SharePoint list

    Your Version Control Log list should have enough columns to be useful as a query surface:

    Column Type Purpose
    Title Text Auto-set to file name
    Action Choice Archived/Restored/Deleted/Locked/Failed
    PolicyName Text Which policy triggered this
    FileName Text The affected file
    VersionLabel Text The affected version
    SiteUrl Text Source site
    LibraryName Text Source library
    Timestamp Date/Time UTC time of action
    FlowRunId Text For cross-referencing with run history
    ErrorDetail Multi-line Error body if action failed

    Setting the FlowRunId is valuable. You can get the current flow's run ID using:

    @{workflow()?['run']?['name']}
    

    This lets you go from a log entry directly to the specific flow run in the Power Automate portal for full debugging context.

    Weekly summary email

    Add a separate scheduled flow that runs Monday morning, queries the Version Control Log for the past week, aggregates counts by action type, and sends a summary email to the governance team. This gives human visibility into what the automation has been doing without requiring anyone to dig into SharePoint lists manually.


    Hands-On Exercise

    Build the complete three-flow version governance system in a test SharePoint environment. Here's a structured progression:

    Part 1 — Environment setup (30 minutes)

    1. Create a SharePoint site called "ProjectDocs" with a document library called "Contracts." Enable versioning: major and minor versions, keep at least 50.
    2. Create a second site called "Preservation" with a library called "VersionArchive."
    3. Create the "Version Restore Requests" list with the schema defined in Flow 2.
    4. Create the "Retention Policies" list with the schema from Flow 3. Add one policy: LibraryName = "Contracts", MaxVersionAgeDays = 7, MaxVersionCount = 5, Action = "DeleteOldVersions", IsActive = Yes.
    5. Upload three test documents. Make 8-10 version edits to each over two days (or manually backdating timestamps via the REST API if you're impatient).

    Part 2 — Build Flow 1 (45 minutes)

    Build the archiver. Run it manually first by clicking "Test" with the "I'll perform the trigger action" option. Check that version archive files appear in the VersionArchive library with the correct naming convention. Verify log entries appear in Version Control Log.

    Part 3 — Build Flow 2 (30 minutes)

    Build the restoration flow. Submit a test restore request via the list. Watch the flow run. Confirm the target file's version history now shows the restored version as current. Verify the log entry.

    Part 4 — Build Flow 3 (45 minutes)

    Build the retention enforcer. Run it manually. Verify that versions older than your configured threshold are deleted. Check that the log records each deletion with the policy name attached.

    Part 5 — Break something intentionally (15 minutes)

    Submit a restore request with a version label that doesn't exist (e.g., "99.0"). Confirm the flow handles it gracefully: Status goes to "Rejected," requester gets notified, and no error appears in the flow's run history (the error was handled, not unhandled).


    Common Mistakes & Troubleshooting

    "The version download URL doesn't work — I'm getting a 403"

    This almost always means your connection's account doesn't have access to that version's URL. Versions are served from the same domain as your SharePoint site, but the URL structure (_vti_history/...) requires that the account has at least Read access to the library. Double-check that your connection account has access to the source library, not just the destination.

    "My filter array returns all versions even when I set IsCurrentVersion to false"

    The JSON from SharePoint's REST API uses lowercase field names in odata=verbose format but the actual values may be returned as strings ("true"/"false") rather than booleans, depending on how you're parsing them. Use @{string(item()?['IsCurrentVersion'])} is equal to false (comparing as strings) or be explicit in your Parse JSON schema that this field is a boolean.

    "The archiver is re-archiving versions it already archived"

    You probably haven't implemented the duplicate check. Before archiving, query your Version Control Log for an item where FileName equals the current file name and VersionLabel equals the current version's label and Action equals "Archived." If that item exists, skip. This is a simple "Get items" action with a filter like:

    FileName eq '@{items('Apply_to_each')?['FileLeafRef']}' and VersionLabel eq '@{items('Apply_to_each_versions')?['VersionLabel']}' and Action eq 'Archived'
    

    If the result count is greater than 0, add a "Terminate" inside the loop scope (or skip with a condition) to bypass that version.

    "The retention flow times out after 30 days on large libraries"

    Power Automate flows have a 30-day maximum run duration, but individual actions time out much sooner. If your library has thousands of files with hundreds of versions each, the nested loops will be slow. Consider breaking the flow into child flows — one parent that iterates over files and fans out to a child flow per file that handles the version logic. The orchestrating child flows and scoped execution in Power Automate lesson covers exactly this architecture.

    "The form digest (X-RequestDigest) is expired by the time I use it"

    Form digest tokens expire after 30 minutes. If your flow takes a long time to process files before reaching the Restore call, the digest may be stale. Move the contextinfo POST call to immediately before the Restore call — don't retrieve it at the start of the flow and use it 45 minutes later.

    "Version deletions are running but the storage quota isn't decreasing"

    SharePoint recalculates storage quotas asynchronously. Deleted versions go to the Recycle Bin first and aren't removed from the quota calculation until the Recycle Bin is emptied. If you need immediate quota relief, add a step that deletes the Recycle Bin item as well — but be aware this makes recovery impossible, so only do this after you've confirmed the archive is in place.

    Tip

    When debugging HTTP calls to SharePoint, add a Compose action after each HTTP response and set its input to body('Send_an_HTTP_request_to_SharePoint'). This captures the full response body in your run history even when things appear to succeed, making it much easier to spot unexpected response structures. Remove these after debugging — they add overhead.


    Summary & Next Steps

    You've built a three-flow version governance system that automates what most organizations handle manually (or don't handle at all). The archiver captures qualifying versions on a schedule and preserves them with meaningful naming across site boundaries. The restoration flow gives document owners self-service access to past versions without IT involvement. The retention enforcer reads policy configuration from a SharePoint list and enforces age and count limits automatically, with a full audit log behind every action.

    The important architectural decisions worth remembering:

    • Store policy as data, not code. Your Retention Policies list means the rules can change without a flow modification. This is the difference between a system you'll maintain easily and one that becomes brittle.
    • Log everything. The Version Control Log isn't overhead — it's the proof that your system works and the tool you'll use when something goes wrong.
    • Duplicate checks are not optional. Without them, scheduled flows re-process work they've already done, creating bloated archives and incorrect log counts.
    • Fail gracefully and loudly. Every external API call can fail. Build error paths that capture the failure, update the log, and notify the right person — then let the flow succeed overall rather than crashing on a single bad version.

    From here, consider these extensions:

    • Add a Legal Hold mode to the retention flow: when a file is flagged, skip all deletion logic and route it to a separate legal hold library instead. This is a one-condition addition to Flow 3 with significant compliance value.
    • Connect the Version Control Log to a Power BI report that shows version activity trends, storage recovered, and policy compliance rate per library. The building real-time Power BI dataset refresh pipelines with Power Automate lesson shows how to keep that report current automatically.
    • If your organization uses metadata-driven document classification, the automating SharePoint and OneDrive metadata tagging with Power Automate lesson shows how to combine classification with lifecycle management — letting documents drive their own retention policy based on their content type.

    Version governance isn't glamorous work, but it's exactly the kind of invisible infrastructure that separates organizations that manage information from organizations that hope for the best when the auditors arrive. Build it once, automate it well, and it runs quietly in the background while everyone else is scrambling.

    Work With Us

    From insight to implementation

    Reading is the start. When you're ready to build the data, automation, or AI systems behind it, our team turns strategy into shipped results.

    Let's Build

    Flow Automation Basics

    Previous

    Automating Microsoft 365 User Onboarding with Power Automate: Provisioning Accounts, Assigning Licenses, and Sending Welcome Emails from a Single Flow

    Next

    Chaining Microsoft 365 Connectors in a Single Flow: Building Multi-Step Automations That Span Outlook, Teams, SharePoint, and Planner Without Losing Data Between Actions

    Related Insights

    Power AutomatePractitioner

    Automating Recurring Calendar-Based Reminders with Power Automate: Building Scheduled Flows That Check SharePoint Dates, Calculate Deadlines, and Send Personalized Outlook Notifications

    22 min
    Power AutomateFoundation

    Implementing Power Automate Flow Trigger Filtering and Trigger Conditions to Reduce Unnecessary Run Consumption in High-Volume Production Environments

    19 min
    Power AutomateFoundation

    Controlling Flow with Loops and Conditionals in Power Automate Desktop: For Each, Loop Until, and If Actions for Practical Desktop Automation

    18 min

    On this page

    • Introduction
    • Prerequisites
    • Understanding SharePoint Version History at the API Level
    • Building the Archive Flow: Preserving Versions Across Sites
    • Flow 1: Scheduled Version Archiver
    • Building the Restoration Flow: Self-Service Version Recovery
    • Flow 2: Version Restoration on Request
    • Enforcing Retention Policies: Pruning and Locking at Scale
    • Flow 3: Retention Policy Enforcer
    • Cross-Site Considerations and Permission Architecture
    • Instrumenting for Observability
    • Hands-On Exercise
    • Common Mistakes & Troubleshooting
    • Summary & Next Steps