Restore deleted Flows as an Admin

close up photo of pink scrabble tiles

As an admin, you will only know too well, that if a user deletes a flow, you will need to raise a call with Microsoft to restore that flow to Power Automate. Until May 2022 that is, when the Restore-AdminFlow cmdlet was released.

There are native actions in Power Automate for adminstering flows but there is no current timescales for releasing an action to restore flows directly. If you were wondering if it was possible to restore flows from Power Automate or Power Apps using the Platform, then I have a solution for you – Azure Runbooks. I have a blog post showing you how I built a Runbook to change the sharing options of SharePoint using Power Automate.

It’s worth noting at this point, that the Restore-AdminFlow cmdlet can only restore non solution aware flows!

Deleting your flows

Accidentally or intentionally, if you delete flows from Power Automate, you will not be able to restore them. You now have up to 28 days to action a restore using PowerShell.

Deleting a flow

In order to restore a flow you must either know the FlowName, i.e. the GUID or the DisplayName, i.e. the friendly name you have given your flow. My demonstration below will return both by determining the flows that have been deleted on a specific enviroment and will use the GUID to restore them.

Using PowerShell to restore a flow

You will first need to install the PowerShell support for PowerApps, available in the guide here. You will also need to be an environment admin for the environment that you wish to restore flows. This is not for end users to restore their own flows but for your IT department, who could adopt this solution to allow self service as I will demonstrate.

I have created two basic PowerShell scripts. The first of which will determine an array of flows that have been deleted in the past 28 days. This is achieved by comparing two tables of data from the Get-AdminFlow CmdLet and outputting either a JSON array for an automated RunBook and Power Automate integration or as a comma seperated string of FlowNames (the flow GUID). The second script will accept a comma seperated list of FlowNames (i.e. GUIDs) and restore each of those flows using Restore-AdminFlow CmdLet. Restored flows will be disabled by default.

#DamoBird365
#PowerShell script to demo how to retrieve an array of deleted flows from a default environment
#Official Docs https://docs.microsoft.com/en-us/powershell/module/microsoft.powerapps.administration.powershell
#www.DamoBird365.com 
#www.youtube.com/c/DamoBird365

param (
    [string]$EnvironmentName = "Default-rg70379a-th7f-45c9-b7d4-hn207c7ca554"
)

#Credentials if using RunBook
#$myCredential = Get-AutomationPSCredential -Name 'PPEnvironmentAdmin' 
#$userName = $myCredential.UserName
#$securePassword = $myCredential.Password
#$password = $myCredential.GetNetworkCredential().Password

#Sign In To PowerApps PowerShell
Add-PowerAppsAccount # -Username $userName -Password $securePassword #If using RunBook

#Get ALL Flows (excluding deleted)
$NonDeletedFlows = Get-AdminFlow -EnvironmentName $EnvironmentName

#Get ALL Flows (including deleted)
$AllFlowsIncDeleted = Get-AdminFlow -EnvironmentName $EnvironmentName -IncludeDeleted $true

#Compare non with all to get deleted
$DeletedFlows = Compare-Object -ReferenceObject $NonDeletedFlows -DifferenceObject $AllFlowsIncDeleted -Property FlowName -PassThru

#Format Result as JSON
$DeletedFlowsJSON = $DeletedFlows | Select-Object -Property FlowName, DisplayName | ConvertTo-Json

Write-Output ($DeletedFlowsJSON)

#If you want a comma seperated string of FlowNames for Testing in PowerShell
$combined = $DeletedFlows | ForEach-Object { $_.FlowName }
$result = $combined -join ','
Write-Output ("")
Write-Output ($result)
#DamoBird365
#PowerShell script to demo how to restore deleted flows from a default environment
#Official Docs https://docs.microsoft.com/en-us/powershell/module/microsoft.powerapps.administration.powershell
#www.DamoBird365.com 
#www.youtube.com/c/DamoBird365

param (
    [string]$FlowsToRestoreString = "59d1cdd1-542e-4c13-8a59-b729221ebef5,7cf92a9d-c345-456b-9123-ce83291ab4b0",
	[string]$EnvironmentName = "Default-rg70379a-th7f-45c9-b7d4-hn207c7ca554"
	
)

#Credentials if using RunBook
#$myCredential = Get-AutomationPSCredential -Name 'PPEnvironmentAdmin' 
#$userName = $myCredential.UserName
#$securePassword = $myCredential.Password
#$password = $myCredential.GetNetworkCredential().Password

#Sign In To PowerApps PowerShell
Add-PowerAppsAccount # -Username $userName -Password $securePassword #If using RunBook

#Split string into an array
$FlowsToRestore = $FlowsToRestoreString.split(",");

#For each FlowName in the array, restore the flow 
$FlowsRestored = foreach ($Flow in $FlowsToRestore)  { Restore-AdminFlow -EnvironmentName $EnvironmentName -FlowName $Flow; Start-Sleep -Seconds 1 }

Write-Output ($FlowsRestored)

I demo how to use these scripts in my video. Note that I have commented out the credentials as used by the RunBook which is perfectly fine if all you want to do is run the PowerShell locally to restore flows ad-hoc.

RunBook Automation

For my Power Automate and subsequent Power App solution, I built two Azure RunBooks using the above scripts. One is appropriately called GetDeletedFlows and will return a JSON Array of deleted flows, the second RestoreFlows, will restore those deleted flows as determined by an input of FlowName GUIDs.

Azure RunBook to restore deleted flows

I have configured Credentials within my Automation Account so that I can call these from the RunBook. I have also installed the PowerApps admin module which is a requirement of running these PowerShell scripts online.

PowerApps Admin module

Restore Flows via Power Automate

To restore flows via Power Automate, you need to use the Premium action Create Job and Get Job for Azure Automation. The RunBook accepts a default environment which you can retrieve from the URL of your Maker Portal and you need to make sure you select “Wait for Job” under advanced. Get Job will then retrieve the JSON Array of deleted flows and it’s with this data that I have simply converted the FlowName GUID’s into an array. You could of course filter this array by Display Name at this point if required and only restore select flows.

With the FlowName (GUIDs) as an Array, we can simply join() them to form a comma seperated list of GUIDs and this can be passed back to the second RunBook to restore those flows. The second RunBook will accept both the default environment and of course the comma seperated list of flows to restore.

View Deleted Flows and Restore via Power Apps

Using the same actions above we can simply take the JSON array output from an equivalent flow called directly from PowerApps and convert to a collection. This can then be displayed within a PowerApp as a Gallery. From the Gallery we could in theory allow multiple selections and restore multiple flows, but for the purpose of my demo I have a flow that will restore a single flow based on the current item being selected. To restore multiple flows, all we need to do is pass a comma seperated list of FlowName GUIDs.

The first Flow triggered from the app will return the JSON array as an output back to the app. As there is no native way to convert a JSON array to a collection, I have used the technique as described in the following post on the Microsoft Forum.

Flow Triggered from PowerApps to get an array of deleted flows

The second flow is triggered by selecting an item on the gallery and the FlowName GUID of the current item is sent to the flow as input in order to pass this to the RunBook.

Flow accepts a GUID in order to restore a deleted flow

The app in terms of appearance is rather basic and includes a Gallery where the items are based on the collection retrieved from the first Power Automate Flow. I trigger this on a manual button press but it could be onvisible of the current screen. The restoration of flows is triggered by selecting a current item and upon completion, I remove the current item from the collection and then refresh the data source. The restored flow should no longer be in the returned data source as the flow has now been restored. Note that it can take up to 30 seconds for the whole process to complete.

Power App interface to restore deleted flows
Share