The “Hey, Scripting Guys!” blog has been retired. There are many useful posts in this blog, so we keep the blog here for historical reference. However, some information might be very outdated and many of the links might not work anymore.
New PowerShell content is being posted to thePowerShell Community blog where members of the community can create posts by submitting content in theGitHub repository.
Use PowerShell to Identify Unassociated Azure Resources

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 onTwitter andFacebook. If you have any questions, send email to me atscripter@microsoft.com, or post your questions on theOfficial Scripting Forum. See you tomorrow. Until then, peace.
Your good friend, Doctor Scripto
PowerShell, Doctor Scripto, Azure, Patrick Mercier
Author

The "Scripting Guys" is a historical title passed from scripter to scripter. The current revision has morphed into our good friend Doctor Scripto who has been with us since the very beginning.
2 comments
Discussion is closed.Login to edit/delete existing comments.
Marcus Ferreira 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
Diego Souza Hello,
Please be aware that Azure Site Recovery managed disks also returns empty ManagedBy! Azure Site Recovery managed disks names use the prefix ‘asrseeddisk-‘.