Keeping your Azure environment clean and cost-efficient can be tricky — especially when unused or “orphaned” resources pile up over time. These can include unattached disks, unassociated public IPs, unused NICs, and more — all quietly incurring charges or cluttering your infrastructure.
In this guide, we’ll walk you through:
-What orphaned Azure resources are
– How to access Azure Resource Graph Explorer
– Pre-built queries to find and audit common orphaned resources
– Tips on cleanup and automation
What Are Orphaned Azure Resources?
An orphaned resource is a resource that’s no longer actively used but still exists in your Azure environment. Examples include:
– A disk that’s not attached to any VM
– A NIC that isn’t associated with anything
– A public IP not bound to any resource
– An empty availability set
– A network security group (NSG) not linked to NICs or subnets
These resources don’t serve a purpose, but you’re still paying for some of them.
Step-by-Step: How to Use Azure Resource Graph Explorer
– Go to the Azure Portal.
– In the search bar, type “Resource Graph Explorer” and open it.
– Select the subscriptions you want to query (top bar).
– Paste any of the following Kusto (KQL) queries into the query editor.
– Run the query and export results as CSV/JSON as needed.
Example Queries to Find Orphaned Azure Resources
1. Unattached Managed Disks
Resources
| where type has "microsoft.compute/disks"
| extend diskState = tostring(properties.diskState)
| where managedBy == "" or diskState == 'Unattached'
| project id, diskState, resourceGroup, location, subscriptionId
Finds disks not attached to any VM (costly orphaned storage).
2. Unattached Network Interfaces (NICs)
Resources
| where type has "microsoft.network/networkinterfaces"
| where "{nicWithPrivateEndpoints}" !has id
| where properties !has 'virtualmachine'
| project id, resourceGroup, location, subscriptionId
Finds NICs that are not linked to VMs or endpoints.
3. Unused Network Security Groups (NSGs)
Resources
| where type =~ 'microsoft.network/networksecuritygroups'
| where isnull(properties.networkInterfaces) and isnull(properties.subnets)
| project id, resourceGroup, subscriptionId, location
These NSGs are not associated with any NIC or subnet — unused.
4. Empty Availability Sets
Resources
| where type =~ 'microsoft.compute/availabilitysets'
| extend VirtualMachines = array_length(properties.virtualMachines)
| where VirtualMachines == 0
| project id, resourceGroup, subscriptionId, location
Availability sets that have no VMs — safe to remove.
5. Unassociated Public IP Addresses
Resources
| where type =~ 'microsoft.network/publicipaddresses'
| extend IpConfig = properties.ipConfiguration.id
| where isempty(IpConfig)
| extend natGateway = properties.natGateway.id
| where isempty(natGateway)
| order by ['name'] asc
Public IPs not linked to a NIC, LB, or NAT Gateway.
What to Do With the Results?
Review before deleting: Just because a resource appears unused doesn’t mean it’s safe to delete. Double-check dependencies!
Tag or Export: Tag items for cleanup, or export to CSV for review by your team.
Automate: Use PowerShell and Azure CLI scripts to remove validated orphaned resources at scale.