To list resource locks in Azure, run Get-AzResourceLock in each subscription, or open the locks page of a subscription, resource group or resource in the Azure portal. A lock is set on 1 scope but covers everything inside it, so a resource can be protected by a lock set on its resource group or subscription. Locks do not protect the data inside a resource.
| Method | Best fit |
|---|---|
| PowerShell | A sortable CSV of every lock in the subscriptions an account can read. |
| Admin centre | A look at the locks on 1 subscription, group or resource, with nothing to install. |
| Altivane | Recommended for recurring reviews across subscriptions, with the groups no lock protects. |
Before you start
Use an Azure account with read access to the subscriptions you want to review. The built-in Reader role, assigned at the subscription or a parent scope, is enough to read locks. The PowerShell example uses the Az.Accounts and Az.Resources modules, and no separate product licence is needed.
Azure has 2 lock levels. The portal calls them Delete and Read-only, and the command line calls them CanNotDelete and ReadOnly. A Delete lock stops a resource being deleted, and a Read-only lock stops it being changed as well. Locks sit on a subscription, a resource group or a resource, never on a management group. The script reads Azure when it runs, exports a CSV and changes nothing. Its finally block disconnects the account, so you may need to sign in again.
Option 1
List resource locks in Azure with PowerShell
Install the modules once and connect to Azure. The script reads the locks of each enabled subscription and writes 1 row per lock.
Install-Module -Name Az.Accounts, Az.Resources -Repository PSGallery -Scope CurrentUser$ErrorActionPreference = 'Stop'
Connect-AzAccount -ErrorAction Stop
try {
$subscriptions = @(Get-AzSubscription | Where-Object State -eq 'Enabled')
if ($subscriptions.Count -eq 0) {
Write-Output 'No enabled subscriptions are available to this account.'
return
}
$marker = '/providers/Microsoft\.Authorization/locks/.*$'
$rows = @(foreach ($subscription in $subscriptions) {
Set-AzContext -Subscription $subscription.Id -Scope Process | Out-Null
foreach ($lock in @(Get-AzResourceLock)) {
$scope = $lock.LockId -replace $marker, ''
$on = 'Resource'
if ($scope -match '^/subscriptions/[^/]+$') {
$on = 'Subscription'
} elseif ($scope -match '^/subscriptions/[^/]+/resourceGroups/[^/]+$') {
$on = 'Resource group'
}
[pscustomobject]@{
Lock = $lock.Name
Level = $lock.Properties.level
On = $on
Scope = $scope
Subscription = $subscription.Name
Notes = $lock.Properties.notes
LockId = $lock.LockId
}
}
})
if ($rows.Count -eq 0) {
Write-Output 'No resource locks were found in the readable subscriptions.'
} else {
$rows |
Sort-Object Subscription, Scope, Lock |
Export-Csv -Path './resource-locks.csv' -NoTypeInformation -Encoding utf8
$readOnly = @($rows | Where-Object Level -eq 'ReadOnly')
Write-Output "$($rows.Count) locks saved to resource-locks.csv."
Write-Output "$($readOnly.Count) of them are ReadOnly."
}
} finally {
Disconnect-AzAccount | Out-Null
}The export has each lock's name, level, what it is on (Subscription, Resource group or Resource), scope, subscription name, notes and lock ID. A lock appears once, against the scope it is set on. An empty result writes a message, not an empty CSV.
To narrow the search, keep only the subscriptions you want in $subscriptions. To keep only Read-only locks, add Where-Object Level -eq 'ReadOnly' before Export-Csv.
Option 2
List resource locks in the Azure portal
- Sign in to the Azure portal with read access to the subscription.
- For a subscription, search for Subscriptions > choose the subscription > Settings > Resource locks.
- For a resource group, search for Resource groups > choose the group > Settings > Locks.
- For a resource, open the resource, then choose Settings > Locks.
- Read each lock's name, type (Delete or Read-only) and notes. A lock set on a parent also covers the resource, so check its group and subscription too.
The portal suits a look at 1 scope. You open each scope's locks page in turn, so use PowerShell when you need every lock in 1 CSV.
Option 3 ยท Recommended for recurring reviews
List resource locks with Altivane
- Open Altivane and choose the tenant.
- Run the Azure Locks report.
- Open the Excel workbook and read the Locks table, where each lock has its level (Cannot delete or Read only), what it is on, its resource group, subscription, notes and lock ID.
- Read the Resource groups without a lock table for the groups nothing protects.
Altivane reads every subscription the connected account can read in 1 run and writes an Excel workbook to keep. The second table lists each resource group with no lock of its own and none on its subscription. A resource inside a listed group may still have a lock. A subscription whose locks could not be read is left out of that table.
Contact usCommon questions
Why does a resource show no lock when it cannot be deleted?
The lock is probably set higher up. A lock on a resource group or subscription is inherited by everything inside it, including resources added later. The lists show a lock against the scope it is set on, so check the resource's group and subscription.
Does a lock protect the data inside a resource?
No. Locks apply to control plane operations, the requests sent to Azure Resource Manager. A Read-only lock on a SQL logical server stops the server being changed or deleted, but data in its databases can still be written.
Can a lock stop me deleting an empty resource group?
Yes. If any resource in a group has a Delete lock, deleting the group is refused as a whole. To find the groups that hold nothing, see how to find empty resource groups in Azure, then check each one for a lock.
Microsoft references
Technical references checked on 8 October 2026. The example scripts have been reviewed and syntax checked; they have not been run against a live tenant.