Summary: Save costs by Identifying Unassociated Resources left behind after deletions in Azure
Q: Hey, Scripting Guy!
How can I quickly identify un-associated resources in my Azure subscription?
A: Hi SH!
At least you know that’s a question to ask! I myself when I first began exploring this new world didn’t realize that when deleting a virtual system in Azure, not all the associated resources are deleted with it!
First things first, if you’ve never done it, you’ll need to install the Azure PowerShell modules. This can be done by following the steps provided here on docs.microsoft.com
Install the Azure PowerShell Module
Then, log on to your subscription using:
Login-AzAccount
Once logged in, we can now use PowerShell to manage things in that mystical place called the Azure Cloud.
In my world, I discovered that network interfaces didn’t get deleted along with their VMs. And after using the web interface from my Azure portal and clicking around to figure out which ones where not associated, I said “self, there has to be a better way!” And so, there was.
Get-AZNetworkInterface
If you just ran that command, like me, you likely have a plethora of text on your screen! So let’s narrow it down.
Get-AzNetworkInterface | Select-Object name, virtualmachine
And there it is. I now know which Network Interface resources are not associated with a virtual machine!
So, if I want to remove those excess ones, I can do:
Get-AzNetworkInterface | Where-Object { $_.virtualmachine -eq $null } | Remove-AzNetworkInterface
A few confirms later (or if I don’t want to validate just add -force), the unassociated Network Interfaces have been removed from my resource group!
So, let’s take it a step further!
Get-AzDisk | Select-Object name,managedby
Where “ManagedBy” is empty, these are unallocated disk, and if you know about Azure, as much as storage costs are cheap, they’re not free!
So this time:
Get-AzDisk | Where-Object { $_.ManagedBy -eq $null } | Remove-AzDisk
And done, left over disks from previous system builds are gone.
So, Get-Az* is a great way to help me clean up my resources, but each one needs a tiny bit of a different approach. For Network Interfaces, I looked for $null on Virtual Machines. For Disks, I sought out $null on ManagedBy and for Network Security Groups:
Get-AZNetworkSecurityGroup | Where-Object { $_.NetworkInterfaces.count -eq 0 } | Select-Object name
Yep, here we look for the number of Network Interfaces the Network Security Group is associated to because an empty array is still an object rendering $null useless in this situation.
As your Azure resource group grows, keeping it clean is both good practice and economical. Hopefully this will help you do that with a few less gray hairs and a bit less late night clicking. Happy PowerShelling!
Patrick Mercier, PFE
So that is all there is to copying multi-valued attributes in Active Directory. Pop by next week as we put on our detective hats to uncover a cool puzzle in Azure.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Forum. See you tomorrow. Until then, peace.
Your good friend, Doctor Scripto
PowerShell, Doctor Scripto, Azure, Patrick Mercier
I’d suggest also filtering the Network Security Group (NSG) with subnet count equals 0, because now NSGs are not only associated to NICs, but also to subnets.
Get-AZNetworkSecurityGroup | Where-Object { $_.NetworkInterfaces.count -eq 0 -And $_.Subnets.Count -eq 0 } | Select Name
Hello,
Please be aware that Azure Site Recovery managed disks also returns empty ManagedBy! Azure Site Recovery managed disks names use the prefix ‘asrseeddisk-‘.