Last active
April 1, 2021 20:18
-
-
Save heaths/a3810f36a56177ae1cbe4cf57af0b02f to your computer and use it in GitHub Desktop.
Example script to delete expired or non-standard named resource groups
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env pwsh | |
# Copyright (c) Microsoft Corporation. All rights reserved. | |
# Licensed under the MIT License. | |
#Requires -Version 6.0 | |
#Requires -PSEdition Core | |
#Requires -Modules @{ModuleName='Az.Accounts'; ModuleVersion='1.6.4'} | |
#Requires -Modules @{ModuleName='Az.Resources'; ModuleVersion='1.8.0'} | |
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] | |
[OutputType([Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels.PSResourceGroup])] | |
param ( | |
[Parameter()] | |
[ValidatePattern('^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$')] | |
[string] $SubscriptionId, | |
[Parameter()] | |
[switch] $Force, | |
[Parameter()] | |
[switch] $AsJob, | |
[Parameter()] | |
[switch] $PassThru | |
) | |
# By default stop for any error. | |
if (!$PSBoundParameters.ContainsKey('ErrorAction')) { | |
$ErrorActionPreference = 'Stop' | |
} | |
# Do not check $Force in conditions below which elides the prompts for -WhatIf. | |
# See https://docs.microsoft.com/powershell/scripting/learn/deep-dives/everything-about-shouldprocess#shouldprocess--force | |
if ($Force) { | |
$ConfirmPreference = 'None' | |
} | |
# Support actions to invoke on exit. | |
$exitActions = @({ | |
if ($exitActions.Count -gt 1) { | |
Write-Verbose 'Running registered exit actions' | |
} | |
}) | |
# This script is intended for interactive users. Make sure they are logged in or fail. | |
$context = Get-AzContext | |
if (!$context) { | |
Write-Error 'You must be already logged in to use this script. Run Connect-AzAccount and try again.' -Category PermissionDenied -RecommendedAction 'Run Connect-AzAccount and try again.' | |
} | |
$currentSubscriptionId = $context.Subscription.Id | |
# If no subscription was specified, try to select the Azure SDK Developer Playground subscription. | |
# Ignore errors to leave the automatically selected subscription. | |
if ($SubscriptionId) { | |
if ($currentSubscriptionId -ne $SubscriptionId) { | |
Write-Verbose "Selecting subscription '$SubscriptionId'" | |
$null = Select-AzSubscription -Subscription $SubscriptionId -WhatIf:$false | |
$exitActions += { | |
Write-Verbose "Selecting previous subscription '$currentSubscriptionId'" | |
$null = Select-AzSubscription -Subscription $currentSubscriptionId -WhatIf:$false | |
} | |
# Update the context. | |
$context = Get-AzContext | |
} | |
} else { | |
if ($currentSubscriptionId -ne $context.Subscription.Id) { | |
Write-Verbose "Attempting to select subscription 'Azure SDK Developer Playground (faa080af-c1d8-40ad-9cce-e1a450ca5b57)'" | |
$null = Select-AzSubscription -Subscription 'faa080af-c1d8-40ad-9cce-e1a450ca5b57' -ErrorAction Ignore -WhatIf:$false | |
# Update the context. | |
$context = Get-AzContext | |
} | |
$SubscriptionId = $context.Subscription.Id | |
$PSBoundParameters['SubscriptionId'] = $SubscriptionId | |
} | |
# Use cache of well-known team subs without having to be authenticated. | |
$wellKnownSubscriptions = @{ | |
'faa080af-c1d8-40ad-9cce-e1a450ca5b57' = 'Azure SDK Developer Playground' | |
'a18897a6-7e44-457d-9260-f2854c0aca42' = 'Azure SDK Engineering System' | |
'2cd617ea-1866-46b1-90e3-fffb087ebf9b' = 'Azure SDK Test Resources' | |
} | |
# Print which subscription is currently selected. | |
$subscriptionName = $context.Subscription.Id | |
if ($wellKnownSubscriptions.ContainsKey($subscriptionName)) { | |
$subscriptionName = '{0} ({1})' -f $wellKnownSubscriptions[$subscriptionName], $subscriptionName | |
} | |
Write-Verbose "Using subscription '$subscriptionName'" | |
try { | |
Write-Verbose "Getting all resource groups in subscription '$subscriptionName'" | |
$resourceGroups = Get-AzResourceGroup | |
foreach ($resourceGroup in $resourceGroups) { | |
if ($resourceGroup.Tags -and $resourceGroup.Tags.ContainsKey('DeleteAfter')) { | |
$deleteAfter = [DateTimeOffset]::MaxValue | |
if ([DateTimeOffset]::TryParse($resourceGroup.Tags['DeleteAfter'], [ref] $deleteAfter) -and $deleteAfter -lt [DateTimeOffset]::Now) { | |
if ($PSCmdlet.ShouldProcess($resourceGroup.ResourceGroupName, 'Delete expired resource group')) { | |
if ($PassThru) { | |
$resourceGroup | |
} | |
$null = Remove-AzResourceGroup $resourceGroup.ResourceGroupName -Force:$true -AsJob:$AsJob | |
} elseif ($WhatIfPreference -and $PassThru) { | |
$resourceGroup | |
} | |
} | |
} elseif ($resourceGroup.ResourceGroupName -notmatch 'rg-.*') { | |
if ($PSCmdlet.ShouldProcess($resourceGroup.ResourceGroupName, 'Delete resource group with non-standard name')) { | |
if ($PassThru) { | |
$resourceGroup | |
} | |
# $null = Remove-AzResourceGroup $resourceGroup.ResourceGroupName -Force:$true -AsJob:$AsJob | |
} elseif ($WhatIfPreference -and $PassThru) { | |
$resourceGroup | |
} | |
} | |
} | |
} finally { | |
$exitActions.Invoke() | |
} | |
<# | |
.SYNOPSIS | |
Deletes resource groups that have expired or do not match standard naming conventions. | |
.DESCRIPTION | |
A resource group that contains a "DeleteAfter" tag will be checked if it has expired. | |
A resource group may also be deleted if it does not match the standard naming convention 'rg-.*'. | |
You can pass -WhatIf to see which ones would be deleted without actually deleting them. | |
You must be logged into Azure to run this command. | |
.PARAMETER SubscriptionId | |
The subscription ID from which to enumerate resource groups. By default this is your current subscription. | |
.PARAMETER Force | |
Do not prompt to delete resource groups. If passed with -WhatIf, -WhatIf takes precedence. | |
.PARAMETER AsJob | |
Delete resource groups in a background job. | |
By default, the script will wait for each resource group to be deleted. | |
.PARAMETER PassThru | |
Returns the resource groups that will be deleted. You can use this with -WhatIf to discover all invalidated resource groups. | |
.EXAMPLE | |
Remove-AzSdResourceGroups -WhatIf | |
See what would be deleted without actually deleting them. | |
.EXAMPLE | |
Remove-AzSdkResourceGroups -Force -AsJob; Get-Job | |
Forcibly remove all invalidated resource groups in a job then see which jobs are running. | |
#> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment