Introduction
When working in Azure or the rest of the Microsoft Cloud environment. One of the preferred tools are Powershell. From time to time, I have customers or random people on docs.microsoft.com Q&A area asking question that is solvable using a script.
If I have the time or if the question peaked my interest, I will do what I can to help in providing or finding a solution.
So, I decided to share these scripts here with a description of function and in some cases a description of what the different cmdlets do. I would like to note that these are scripts that I have used or provided for a specific purpose and thus, they are limited in features to what is required of them.
The idea is that if you are searching for a specific issue, you might come across this blog post – in which case one of the scripts might be able to help you out with the the task you try to accomplish.
All scripts will be located in this public Github repository and are everyone is allowed to use or modify them within the boundary of the MIT License.
List empty vnet
This script were created due to what seems to be an expanded wish to clean up on orphan resources in Azure environments. So this script runs through either a specific subscription or all subscriptions in a tenant and looks for all empty vnets.
It is mandatory to provide the tenantID from the tenant in question, and if a subscription name or ID is provided, then it will only look through the resources in this specific subscription.
The result will be saved on the following location “C:\Temp\empty vnet list.csv” unless another position is specified using the -exportpath variable
Required modules
1 |
Install-module az |
The script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
<# .COPYRIGHT Copyright (c) MMT Consult. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information. Version 0.0.2 Author: Martin Meiner Tästensen contact: support@mmt-consult.dk #> Param( [parameter(mandatory = $false, HelpMessage = "Provide subscription id to only verify the specific subscription")] [string]$subscriptionId = $null, [parameter(mandatory = $false, HelpMessage = "Provide subscription name to only verify the specific subscription")] [string]$subscriptionName = $null, [parameter(mandatory = $true, HelpMessage = "Provide tenantid for the specific tenant")] [string]$tenantid, [parameter(mandatory = $false, HelpMessage = "Path for CSV export file")] [string]$exportpath = "C:\Temp\empty vnet list.csv", [parameter(mandatory = $false, HelpMessage = "define if the export is based on subnet or vnet")] [validateset("simple","full")] [string]$exportdetail = "full" ) # Verify if a connection to the expected tenant already exists, and if not create it. $connection = Get-AzContext if($connection.Tenant.id -eq $tenantid) { write-host "Already connected to the correct tenant, no further action nessesary" -ForegroundColor green } else{Connect-AzAccount -Tenant $tenantid} # Dependent on choice for parameters, get data for all subscriptions or only the one selected if([string]::IsNullOrWhiteSpace($subscriptionId) -or [string]::IsNullOrWhiteSpace($subscriptionName)) { $subscriptions = Get-AzSubscription -TenantId $tenantid } elseif ([string]::IsNullOrWhiteSpace($subscriptionId)) { $subscriptions = Get-AzSubscription -TenantId $tenantid -SubscriptionId $subscriptionId } elseif ([string]::IsNullOrWhiteSpace($subscriptionName)) { $subscriptions = Get-AzSubscription -TenantId $tenantid -SubscriptionName $subscriptionName } # Creationg of the arrays that will be used later in the script $vnetexport = @() $emptyvnets = @() $notemptyvnets = @() $usedvnets = @() <# Run through each subscription, and pull the data required to verify the vnet. This process can take some time, depending on the amount of VNET's and subscriptions. The data will be saved into a new object, that will be based on subnets. #> foreach($subscription in $subscriptions) { $connecttosubscription = Select-AzSubscription -Tenant $tenantid -Subscription $subscription.Id $virtualnetworks = Get-AzVirtualNetwork foreach($virtualnetwork in $virtualnetworks) { $subnetvnetlist = @() foreach($subnet in $virtualnetwork.subnets.name) { $subnetvnetlist += Get-AzVirtualNetworkSubnetConfig -VirtualNetwork $virtualnetwork -Name $subnet } foreach($i in $subnetvnetlist) { $p = @{ VNETname = $virtualnetwork.Name VNETRessourcegroup = $virtualnetwork.ResourceGroupName VNETLocation = $virtualnetwork.Location VNETId = $virtualnetwork.Id -join ',' VNETResourceGuid = $virtualnetwork.ResourceGuid subscriptionName = $subscription.Name subscriptionId = $subscription.Id tenantid = $subscription.TenantId subnetname = $i.Name subnetid = $i.Id -join ',' subnetIPconfig = $i.IpConfigurations.id -join ',' subnetResourceNavigationLinks = $i.ResourceNavigationLinks -join ',' subnetServiceAssociationLinks = $i.ServiceAssociationLinks.id -join ',' subnetNetworkSecurityGroup = $i.NetworkSecurityGroup subnetRouteTable = $i.RouteTable subnetNatGateway = $i.NatGateway subnetServiceEndpoints = $i.ServiceEndpoints.service -join ',' subnetServiceEndpointPolicies = $i.ServiceEndpointPolicies -join ',' subnetPrivateEndpoints = $i.PrivateEndpoints.id -join ',' subnetEndpointNetworkPolicies = $i.EndpointNetworkPolicies subnetLinkServiceNetworkPolicies = $i.LinkServiceNetworkPolicies -join ',' } $objcmddata = New-Object -TypeName psobject -Property $p $vnetexport += $objcmddata } } } <# Verify if the vnet's are empty. It will have to run through each subnet multiple times since each subnet are saved in the same entry. No calls are required for this part, so it will go fairly quickly #> foreach($resource in $vnetexport) { if($usedvnets.VNETID -notcontains $resource.VNETID) { $tempvalue = @() $usedvnets += $resource foreach($i in $vnetexport) { if($i.VNETID -eq $resource.VNETID) { $tempvalue += $i } } if([string]::IsNullOrWhiteSpace($tempvalue.subnetIPconfig) -and ` [string]::IsNullOrWhiteSpace($tempvalue.subnetServiceEndpointPolicies) -and ` [string]::IsNullOrWhiteSpace($tempvalue.subnetLinkServiceNetworkPolicies) -and ` [string]::IsNullOrWhiteSpace($tempvalue.subnetServiceEndpoints) -and ` [string]::IsNullOrWhiteSpace($tempvalue.subnetServiceAssociationLinks) -and ` [string]::IsNullOrWhiteSpace($tempvalue.subnetPrivateEndpoints)) { $emptyvnets += $tempvalue } else { $notemptyvnets += $tempvalue } } } <# Export the data to CSV. Note: This data can be based on either the VNET or subnet, dependent on your wishes #> if($exportdetail -eq "simple") { $emptyvnets | ` Select-Object VNETname, VNETRessourcegroup, VNETLocation, VNETResourceGuid, subscriptionName, subnetname | ` Export-Csv -Path $exportpath -Delimiter ';' -Encoding unicode -NoTypeInformation } elseif($exportdetail -eq "full") { $emptyvnets | ` Select-Object VNETname, VNETRessourcegroup, VNETLocation, VNETResourceGuid, subscriptionName, subnetname, subnetIPconfig, ` subnetResourceNavigationLinks, subnetServiceAssociationLinks, subnetNetworkSecurityGroup, subnetRouteTable, ` subnetNatGateway, subnetServiceEndpoints, subnetServiceEndpointPolicies, subnetPrivateEndpoints, ` subnetEndpointNetworkPolicies, subnetLinkServiceNetworkPolicies, tenantid, VNETId, subscriptionId, subnetid | ` Export-Csv -Path $exportpath -Delimiter ';' -Encoding unicode -NoTypeInformation } write-host "Script is completed, please find the export file at $exportpath" -ForegroundColor green |
The result
The result will be a CSV file that you can open in your preferred CSV editor, which contains the following headlines
- VNETname
- VNETRessourcegroup
- VNETLocation
- VNETResourceGuid
- subscriptionName
- subnetname
- subnetIPconfig
- subnetResourceNavigationLinks
- subnetServiceAssociationLinks
- subnetNetworkSecurityGroup
- subnetRouteTable
- subnetNatGateway
- subnetServiceEndpoints
- subnetServiceEndpointPolicies
- subnetPrivateEndpoints
- subnetEndpointNetworkPolicies
- subnetLinkServiceNetworkPolicies
- tenantid
- VNETId
- subscriptionId
- subnetid
Final thoughts
Thank you for reading through this post. Hopefully, it helped you solve a problem or you might just have used it for getting inspiration for a script yourself.
If you have any questions or feedback, please feel free to comment here in the comments or using the contact form
0 Comments