{"id":86555,"date":"2019-10-30T01:00:22","date_gmt":"2019-10-30T09:00:22","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/scripting\/?p=86555"},"modified":"2019-10-29T05:43:38","modified_gmt":"2019-10-29T13:43:38","slug":"use-powershell-to-identify-unassociated-azure-resources","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-powershell-to-identify-unassociated-azure-resources\/","title":{"rendered":"Use PowerShell to Identify Unassociated Azure Resources"},"content":{"rendered":"<p><strong>Summary<\/strong>: Save costs by Identifying Unassociated Resources left behind after deletions in Azure<\/p>\n<p>Q: Hey, Scripting Guy!<\/p>\n<p>How can I quickly identify un-associated resources in my Azure subscription?<\/p>\n<p>A: Hi SH!<\/p>\n<p>At least you know that\u2019s a question to ask! I myself when I first began exploring this new world didn\u2019t realize that when deleting a virtual system in Azure, not all the associated resources are deleted with it!<\/p>\n<p>First things first, if you\u2019ve never done it, you\u2019ll need to install the Azure PowerShell modules. This can be done by following the steps provided here on docs.microsoft.com<\/p>\n<p><a href=\"https:\/\/docs.microsoft.com\/en-us\/powershell\/azure\/install-az-ps?view=azps-2.8.0\">Install the Azure PowerShell Module<\/a><\/p>\n<p>Then, log on to your subscription using:<\/p>\n<pre class=\"lang:ps decode:true \">Login-AzAccount<\/pre>\n<p>Once logged in, we can now use PowerShell to manage things in that mystical place called the Azure Cloud.<\/p>\n<p>In my world, I discovered that network interfaces didn\u2019t 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 \u201cself, there has to be a better way!\u201d And so, there was.<\/p>\n<pre class=\"lang:ps decode:true\">Get-AZNetworkInterface<\/pre>\n<p>If you just ran that command, like me, you likely have a plethora of text on your screen! So let\u2019s narrow it down.<\/p>\n<pre class=\"lang:ps decode:true\">Get-AzNetworkInterface | Select-Object name, virtualmachine\r\n<\/pre>\n<p><img decoding=\"async\" class=\"alignnone wp-image-86556\" src=\"http:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/Get-AZNetworkInterface.png\" alt=\"\" width=\"705\" height=\"196\" srcset=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/Get-AZNetworkInterface.png 1540w, https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/Get-AZNetworkInterface-300x83.png 300w, https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/Get-AZNetworkInterface-768x213.png 768w, https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/Get-AZNetworkInterface-1024x285.png 1024w\" sizes=\"(max-width: 705px) 100vw, 705px\" \/><\/p>\n<p>And there it is. I now know which Network Interface resources are not associated with a virtual machine!<\/p>\n<p>So, if I want to remove those excess ones, I can do:<\/p>\n<pre class=\"lang:ps decode:true \">Get-AzNetworkInterface | Where-Object { $_.virtualmachine -eq $null } | Remove-AzNetworkInterface<\/pre>\n<p>A few confirms later (or if I don\u2019t want to validate just add -force), the unassociated Network Interfaces have been removed from my resource group!<\/p>\n<p>So, let\u2019s take it a step further!<\/p>\n<pre class=\"lang:ps decode:true \">Get-AzDisk | Select-Object name,managedby<\/pre>\n<p><img decoding=\"async\" class=\"alignnone wp-image-86557\" src=\"http:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/Get-AZNetworkInterface2.png\" alt=\"\" width=\"1265\" height=\"206\" srcset=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/Get-AZNetworkInterface2.png 1625w, https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/Get-AZNetworkInterface2-300x49.png 300w, https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/Get-AZNetworkInterface2-768x125.png 768w, https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/10\/Get-AZNetworkInterface2-1024x167.png 1024w\" sizes=\"(max-width: 1265px) 100vw, 1265px\" \/><\/p>\n<p>Where \u201cManagedBy\u201d is empty, these are unallocated disk, and if you know about Azure, as much as storage costs are cheap, they\u2019re not free!<\/p>\n<p>So this time:<\/p>\n<pre class=\"lang:ps decode:true \">Get-AzDisk | Where-Object { $_.ManagedBy -eq $null } | Remove-AzDisk<\/pre>\n<p>And done, left over disks from previous system builds are gone.<\/p>\n<p>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:<\/p>\n<pre class=\"lang:ps decode:true \">Get-AZNetworkSecurityGroup | Where-Object { $_.NetworkInterfaces.count -eq 0 } | Select-Object name<\/pre>\n<p>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.<\/p>\n<p>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!<\/p>\n<p>Patrick Mercier, PFE<\/p>\n<p>So that is all there is to copying multi-valued attributes in Active Directory.\u00a0 Pop by next week as we put on our detective hats to uncover a cool puzzle in Azure.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\">Official Scripting Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Your good friend, Doctor Scripto<\/strong><\/p>\n<p>PowerShell, Doctor Scripto, Azure, Patrick Mercier<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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\u2019s a question to ask! I myself when I first began exploring this new world didn\u2019t realize that when deleting [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[759,1739,1738],"tags":[476,1740,1701,377],"class_list":["post-86555","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure","category-doctor-scripto","category-powershell","tag-azure","tag-doctor-scripto","tag-patrick-mercier","tag-powershell"],"acf":[],"blog_post_summary":"<p>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\u2019s a question to ask! I myself when I first began exploring this new world didn\u2019t realize that when deleting [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/86555","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=86555"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/86555\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=86555"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=86555"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=86555"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}