Orphaned resources in Power Platform—such as unused apps, abandoned flows, and inactive environments—can clutter the system, consume licenses, and pose security risks. Using PowerShell, administrators can detect, audit, and remove these orphaned resources to maintain a clean and efficient Power Platform environment.
Step 1: Prerequisites
1. Install and Import PowerShell Modules
Before running the scripts, ensure you have the required PowerShell modules installed:
Install-Module -Name Microsoft.PowerApps.Administration.PowerShell -Force
Install-Module -Name Microsoft.PowerApps.PowerShell -Force
Then, import the modules:
Import-Module Microsoft.PowerApps.Administration.PowerShell
Import-Module Microsoft.PowerApps.PowerShell
2. Authenticate to Power Platform
Run the following command and sign in with admin credentials:
Add-PowerAppsAccount
You’re now connected and ready to manage orphaned resources.
Step 2: Detecting Orphaned Resources
1. Find Unused Power Apps
To list apps that haven’t been used in 90+ days, run:
$unusedApps = Get-AdminPowerApp | Where-Object { $_.LastModifiedTime -lt (Get-Date).AddDays(-90) }
$unusedApps | Select-Object DisplayName, AppName, LastModifiedTime | Format-Table -AutoSize
2. Find Orphaned Power Automate Flows
To list flows with no owner or inactive for 90+ days:
$orphanedFlows = Get-AdminFlow | Where-Object { $_.CreatedBy -eq $null -or $_.LastModifiedTime -lt (Get-Date).AddDays(-90) }
$orphanedFlows | Select-Object DisplayName, EnvironmentName, CreatedBy, LastModifiedTime | Format-Table -AutoSize
3. Find Unused Environments
To identify environments without active apps, flows, or users:
$unusedEnvironments = Get-AdminEnvironment | Where-Object { $_.LastModifiedTime -lt (Get-Date).AddDays(-180) -and $_.NumberOfApps -eq 0 -and $_.NumberOfFlows -eq 0 }
$unusedEnvironments | Select-Object DisplayName, EnvironmentName, LastModifiedTime | Format-Table -AutoSize
4. Find Unused Dataverse Tables
To list tables not updated in 180+ days:
$unusedTables = Get-CdsTable -EnvironmentName "Default" | Where-Object { $_.LastModifiedTime -lt (Get-Date).AddDays(-180) }
$unusedTables | Select-Object DisplayName, LogicalName, LastModifiedTime | Format-Table -AutoSize
Now we have a list of orphaned resources. Next, we’ll remove them.
Step 3: Removing Orphaned Resources
1. Delete Unused Power Apps
To remove apps not used for 90+ days, run:
$unusedApps | ForEach-Object { Remove-AdminPowerApp -AppName $_.AppName -Confirm:$false }
2. Delete Orphaned Flows
To remove flows with no owner or inactive for 90+ days:
$orphanedFlows | ForEach-Object { Remove-AdminFlow -EnvironmentName $_.EnvironmentName -FlowName $_.FlowName -Confirm:$false }
3. Delete Unused Environments
To remove environments without active users:
$unusedEnvironments | ForEach-Object { Remove-AdminEnvironment -EnvironmentName $_.EnvironmentName -Confirm:$false }
4. Delete Unused Dataverse Tables
To remove tables not updated in 180+ days:
$unusedTables | ForEach-Object { Remove-CdsTable -EnvironmentName "Default" -LogicalName $_.LogicalName -Confirm:$false }
All orphaned resources are now cleaned up.
Step 4: Automating the Process
To automate orphaned resource cleanup, create a scheduled PowerShell script:
- Save the script as
Cleanup-PowerPlatform.ps1
:
# Authenticate
Add-PowerAppsAccount
# Detect and Remove Orphaned Power Apps
$unusedApps = Get-AdminPowerApp | Where-Object { $_.LastModifiedTime -lt (Get-Date).AddDays(-90) }
$unusedApps | ForEach-Object { Remove-AdminPowerApp -AppName $_.AppName -Confirm:$false }
# Detect and Remove Orphaned Flows
$orphanedFlows = Get-AdminFlow | Where-Object { $_.CreatedBy -eq $null -or $_.LastModifiedTime -lt (Get-Date).AddDays(-90) }
$orphanedFlows | ForEach-Object { Remove-AdminFlow -EnvironmentName $_.EnvironmentName -FlowName $_.FlowName -Confirm:$false }
# Detect and Remove Unused Environments
$unusedEnvironments = Get-AdminEnvironment | Where-Object { $_.LastModifiedTime -lt (Get-Date).AddDays(-180) -and $_.NumberOfApps -eq 0 -and $_.NumberOfFlows -eq 0 }
$unusedEnvironments | ForEach-Object { Remove-AdminEnvironment -EnvironmentName $_.EnvironmentName -Confirm:$false }
# Detect and Remove Unused Dataverse Tables
$unusedTables = Get-CdsTable -EnvironmentName "Default" | Where-Object { $_.LastModifiedTime -lt (Get-Date).AddDays(-180) }
$unusedTables | ForEach-Object { Remove-CdsTable -EnvironmentName "Default" -LogicalName $_.LogicalName -Confirm:$false }
- Schedule the script in Task Scheduler:
- Open Task Scheduler
- Click Create Basic Task
- Set recurrence to weekly or monthly
- Choose Start a Program → PowerShell.exe
- Add script path:
-File "C:\Scripts\Cleanup-PowerPlatform.ps1"
- Click Finish
This ensures regular cleanup of orphaned Power Platform resources.