Restore removed files in SharePoint with Power Automate
Table of contents:
Having the trigger in Power Automate called “When a file is deleted” many asks if there is a possibility to restore that removed file or delete it permanently? Yes it is. Let me show you how.
RecycleBin object
The best way to accomplish this is to use SP.RecycleBinItem
object from SharePoint’s Core Objects’ Library (more). The object has two methods:
- deleteObject – removes item from the recycle bin permanently
- restore – restores the item from the recycle bin
Both methods can be called via REST endpoints:
http://<sitecollection>/<site>/_api/web/RecycleBin(recyclebinitemid)/deleteObject()
http://<sitecollection>/<site>/_api/web/RecycleBin(recyclebinitemid)/restore()
Note: if you are building the solution for the web that is a root of the site collection or for the modern team/ communication site, then replace web with site, to get access to the site recycle bin.
The key challenge to use them is: how to obtain the “recyclebinitemid
“. Let me show you how.
When a file is deleted
This trigger is fired once an item is deleted in SharePoint (source). The action has a very limited number of outcomes and they are somehow not very much useful:
{ "ID": [SharePoint Library Item ID], "Name": "[Display name]", "FileNameWithExtension": "[Display name with extension]", "DeletedByUserName": "[Name and lastname of the user]", "TimeDeleted": "[Timestamp]", "IsFolder": [true/false] }
The information scope we can get about each deleted file, as we call http://<sitecollection>/<site>/_api/web/RecycleBin
endpoint is much wider. What is missing in data returned from trigger is information about the path, under which the file was originally present and recycle bin item id, that we can use to restore or permanently delete file. How to get it? See below.
Recycle Bin Item ID
The way you can get it is the following:
- Call
http://<sitecollection>/<site>/_api/web/RecycleBin
endpoint using Send an HTTP request to SharePoint action. - Filter returned list to leave only the item that matches deleted item name and extension using Filter array action.
- Parse returned JSON.
- Restore the item using Recycle Bin Item ID, using Send an HTTP request to SharePoint action.
In step no. 2 use: body('Get_files_from_Recycle_Bin')['d']['results']
for “From” and item()['Title']
is equal to triggerBody()?['FileNameWithExtension']
for filter.
Then parse the item’s JSON and use body('Parse_JSON')['Id']
as a parameter in Uri to restore the item: _api/site/RecycleBin('@{body('Parse_JSON')?['Id']}')/restore()
.
Why is it useful?
This simple, but important functionality can help you in governing SharePoint files, which is the thing now. Having the possibility to remove a file is a privilege’s of most users, however adding additional layer to review if the file can be actually removed and then eventually restore it is another case.
Also, for all those scenarios where you need to sync data between libraries or SPO and your on-prem world, this trigger is also very useful.
If you have any questions, leave them in comments below. Thanks!
Taylor Steele
Hi,
Are these flows still working for you? I noticed that the HTTP request has started only returning items where the “DeletedByEmail” field matches the account used for the connector.
Cheers
Tomasz Poszytek
Try triggering this flow using “Child Flow” approach, so to run it with system account permissions: https://poszytek.eu/en/microsoft-en/office-365-en/powerautomate-en/elevated-permissions-in-microsoft-flow/
Didier
I have the same issue. Flow or flow called as a child flow is returning only delete user for user specified in SharePoint HTTP Call. What is the permission needed to get all deleted items ?
And what’s strange is that recycle bin shows all items and allow me to restore all items (not only mine deleted).
kr
Tomasz Poszytek
Then it seems, this endpoint is limited. Unfortunately there is no related endpoint in Graph API.
Niko Van Beersel
Hi Tomasz,
I’m trying to reapply this method for when a list item is deleted instead of a file (see no reason why that wouldn’t work – hope you agree 🙂 ).
I’m however not sure how to do the Parse JSON step… Can you explain what to write there in the Schema to get he Id correctly structured?
Tomasz Poszytek
Every time you’re in such “doubt” make a test run of your workflow and investigate what the trigger (or other action) returns. Then grab that outputs, it’s always a JSON and simply use it in “Parse JSON” action via the sample payload option.
Sarah Newman
Hi Tomasz, I have found that if I call web/RecycleBin I get just my recycle bin and if I use site/RecycleBin I appear to get the admin recycle bin. Is that what you expect?
Tomasz Poszytek
Good question. Web/Site in terms of Site Collection (not a regular subsite) should be the same thing.
Majing
I wonder how can I empty the recycle bin by http call?
Tomasz Poszytek
You can’t purge it all at once. Only item by item: https://docs.microsoft.com/en-us/previous-versions/office/sharepoint-visio/jj245382(v=office.15)
Majing
is there a way to delete/empty the recycle bin by API?
Tomasz Poszytek
Not to purge the whole at once. This is item by item. https://docs.microsoft.com/en-us/previous-versions/office/sharepoint-visio/jj245382(v=office.15)
Ulf
Hey Tomasz,
two questions:
1)Why you able to filter directly the response of the GET Request? In my case he tells me the response is an object and not an array…
2)I need a information about a specific property of the deleted file to use it in the further process. Can you give me a hint how to get a property of a deledete file?
Tomasz Poszytek
I am filtering d.results from the response body, not the body itself. Response contains table. As per second questions – as long the file is in recycle bin, you cannot get any metadata it used to have as it was in original location.
DARKLING
Hi Tomasz.
When calling https://******cloud.sharepoint.com/sites/****/_api/Web/recyclebin
I only see the authenticated user deleted files. The account is admin so how do I see all deleted files for all users?
Regards
Tomasz Poszytek
Yes, the workflow should work in a context of specific user so therefore has access to that user’s removed files. You can as well try to use “_api/site/RecycleBin” – once file is moved from web level, there you can access all files.
Fernando Domínguez Martín
How to force or overwrite this operation if same folder or item name exists in destination? It cause errors and no restore
Tomasz Poszytek
This is not possible. API doesn’t deliver such a functionality. In this case I’d say that if flow fails because of this reason, build logic that deletes/ renames existing file and then attempts to restore it again.
JV
Hi Tomasz, I’m encountering an issue where when sending the HTTP request to restore the file, I get a returned code of 401 saying UNAUTHORIZED. I’ve tested that I’m able to manually restore the exact same file from the recycle bin using the SharePoint UI, and I’ve also been able to perform some other SharePoint API calls in other Power Automate flows that use POST methods. Any idea what I’m doing incorrectly?
Tomasz Poszytek
Maybe you are trying to restore a file from a site collection bin, not the web one? Do you have site collection admin permissions or could you grant yourself and check again?
AD
Hi Tomasz,
When I try to restore the item I get this:
“Unable to process template language expressions in action ‘Send_an_HTTP_request_to_SharePoint’ inputs at line ‘1’ and column ‘21477’: ‘The template language expression ‘body(‘Parse_JSON’)?[‘Id’]’ cannot be evaluated because property ‘Id’ cannot be selected. Array elements can only be selected using an integer index. Please see https://aka.ms/logicexpressions for usage details.’.”
Tomasz Poszytek
Hi, please check what’s the outcomes of the Parse JSON action in your case. Maybe you have a different schema?
Samuel
Hi Tomasz!
Great post, thanks for sharing. I’m facing an issue when retrieving files from recycle bin, Power Automate returns a bad gateway error. When trying via web with the uri, I get the error “The attempted operation is prohibited because it exceeds the list view threshold”. I guess because there are thousands of files there (most of them are elements deleted from lists that can be permanently deleted).
Any way to handle this situation? Thank you!
Tomasz Poszytek
This is odd, because the endpoints are just accessing a specific item in the bin, not the wider collection. I have no idea if there is an option to use $filter statement in that calls. What is happening when you try to restore a file manually, directly from the recycle bin?