mirror of
https://dev.azure.com/effectory/Survey%20Software/_git/Cloud%20Engineering
synced 2026-02-27 18:52:18 +01:00
Merged PR 51902: updated keyvaults rbac column
updated keyvaults rbac column added scripts to detected unused resources Related work items: #103196
This commit is contained in:
@@ -72,7 +72,7 @@ foreach ($managementGroup in $managementGroups)
|
|||||||
$resourceCheck.ManagementGroupId = $managementGroup.Id
|
$resourceCheck.ManagementGroupId = $managementGroup.Id
|
||||||
$resourceCheck.ManagementGroupName = $managementGroup.DisplayName
|
$resourceCheck.ManagementGroupName = $managementGroup.DisplayName
|
||||||
$resourceCheck.SubscriptionId = $subscription.Id
|
$resourceCheck.SubscriptionId = $subscription.Id
|
||||||
$resourceCheck.SubscriptionName = $subscription.Name
|
$resourceCheck.SubscriptionName = $subscription.DisplayName
|
||||||
$resourceCheck.ResourceGroup = $vaultWithAllProps.ResourceGroupName
|
$resourceCheck.ResourceGroup = $vaultWithAllProps.ResourceGroupName
|
||||||
$resourceCheck.ResourceId = $vaultWithAllProps.ResourceId
|
$resourceCheck.ResourceId = $vaultWithAllProps.ResourceId
|
||||||
$resourceCheck.Location = $vaultWithAllProps.Location
|
$resourceCheck.Location = $vaultWithAllProps.Location
|
||||||
|
|||||||
@@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
class ResourceCheck {
|
class ResourceCheck {
|
||||||
[string] $ResourceId = ""
|
[string] $ResourceId = ""
|
||||||
[string] $Location = ""
|
[string] $ManagementGroupId = ""
|
||||||
[string] $ResourceName = ""
|
[string] $ManagementGroupName = ""
|
||||||
[string] $ResourceGroup = ""
|
|
||||||
[string] $SubscriptionId = ""
|
[string] $SubscriptionId = ""
|
||||||
[string] $SubscriptionName = ""
|
[string] $SubscriptionName = ""
|
||||||
|
[string] $ResourceGroup = ""
|
||||||
|
[string] $ResourceName = ""
|
||||||
|
[string] $Location = ""
|
||||||
[string] $Tag_Team = ""
|
[string] $Tag_Team = ""
|
||||||
[string] $Tag_Product = ""
|
[string] $Tag_Product = ""
|
||||||
[string] $Tag_Environment = ""
|
[string] $Tag_Environment = ""
|
||||||
@@ -30,12 +32,22 @@ Write-Host "====================================================================
|
|||||||
[string] $date = Get-Date -Format "yyyy-MM-dd HHmm"
|
[string] $date = Get-Date -Format "yyyy-MM-dd HHmm"
|
||||||
$fileName = ".\$date azure_key_vaults.csv"
|
$fileName = ".\$date azure_key_vaults.csv"
|
||||||
|
|
||||||
foreach ($subscription in $subscriptions)
|
$managementGroups = Get-AzManagementGroup
|
||||||
|
|
||||||
|
foreach ($managementGroup in $managementGroups)
|
||||||
{
|
{
|
||||||
Write-Host "----------------------------------------------------------------------------------------------------------------------------------------------------------------------"
|
Write-Host "----------------------------------------------------------------------------------------------------------------------------------------------------------------------"
|
||||||
|
Write-Host "Management group [$($managementGroup.Name)]"
|
||||||
|
|
||||||
Set-AzContext -SubscriptionId $subscription.Id
|
$subscriptions = Get-AzManagementGroupSubscription -Group $managementGroup.Name | Where-Object State -eq "Active"
|
||||||
|
|
||||||
|
foreach ($subscription in $subscriptions)
|
||||||
|
{
|
||||||
|
Write-Host "----------------------------------------------------------------------------------------------------------------------------------------------------------------------"
|
||||||
|
$scope = $subscription.Id.Substring($subscription.Parent.Length, $subscription.Id.Length - $subscription.Parent.Length)
|
||||||
|
$subscriptionId = $scope.Replace("/subscriptions/", "")
|
||||||
|
Write-Host "Subscription [$($subscription.DisplayName) - $subscriptionId]"
|
||||||
|
Set-AzContext -SubscriptionId $subscriptionId | Out-Null
|
||||||
Write-Host "----------------------------------------------------------------------------------------------------------------------------------------------------------------------"
|
Write-Host "----------------------------------------------------------------------------------------------------------------------------------------------------------------------"
|
||||||
|
|
||||||
$allResourceGroups = Get-AzResourceGroup
|
$allResourceGroups = Get-AzResourceGroup
|
||||||
@@ -51,13 +63,17 @@ foreach ($subscription in $subscriptions)
|
|||||||
|
|
||||||
$vaultWithAllProps = Get-AzKeyVault -ResourceGroupName $group.ResourceGroupName -Name $vault.VaultName
|
$vaultWithAllProps = Get-AzKeyVault -ResourceGroupName $group.ResourceGroupName -Name $vault.VaultName
|
||||||
|
|
||||||
|
$enabledRBAC = $vaultWithAllProps.EnableRbacAuthorization -eq "TRUE"
|
||||||
|
|
||||||
[ResourceCheck] $resourceCheck = [ResourceCheck]::new()
|
[ResourceCheck] $resourceCheck = [ResourceCheck]::new()
|
||||||
|
$resourceCheck.ManagementGroupId = $managementGroup.Id
|
||||||
|
$resourceCheck.ManagementGroupName = $managementGroup.DisplayName
|
||||||
$resourceCheck.ResourceId = $vaultWithAllProps.ResourceId
|
$resourceCheck.ResourceId = $vaultWithAllProps.ResourceId
|
||||||
$resourceCheck.Location = $vaultWithAllProps.Location
|
$resourceCheck.Location = $vaultWithAllProps.Location
|
||||||
$resourceCheck.ResourceName = $vaultWithAllProps.VaultName
|
$resourceCheck.ResourceName = $vaultWithAllProps.VaultName
|
||||||
$resourceCheck.ResourceGroup = $vaultWithAllProps.ResourceGroupName
|
$resourceCheck.ResourceGroup = $vaultWithAllProps.ResourceGroupName
|
||||||
$resourceCheck.SubscriptionId = $subscription.Id
|
$resourceCheck.SubscriptionId = $subscription.Id
|
||||||
$resourceCheck.SubscriptionName = $subscription.Name
|
$resourceCheck.SubscriptionName = $subscription.DisplayName
|
||||||
$resourceCheck.Tag_Team = $vaultWithAllProps.Tags.team
|
$resourceCheck.Tag_Team = $vaultWithAllProps.Tags.team
|
||||||
$resourceCheck.Tag_Product = $vaultWithAllProps.Tags.product
|
$resourceCheck.Tag_Product = $vaultWithAllProps.Tags.product
|
||||||
$resourceCheck.Tag_Environment = $vaultWithAllProps.Tags.environment
|
$resourceCheck.Tag_Environment = $vaultWithAllProps.Tags.environment
|
||||||
@@ -65,7 +81,7 @@ foreach ($subscription in $subscriptions)
|
|||||||
$resourceCheck.Tag_CreatedOnDate = $vaultWithAllProps.Tags.CreatedOnDate
|
$resourceCheck.Tag_CreatedOnDate = $vaultWithAllProps.Tags.CreatedOnDate
|
||||||
$resourceCheck.Tag_Deployment = $vaultWithAllProps.Tags.drp_deployment
|
$resourceCheck.Tag_Deployment = $vaultWithAllProps.Tags.drp_deployment
|
||||||
$resourceCheck.Prop_EnablePurgeProtection = $vaultWithAllProps.EnablePurgeProtection
|
$resourceCheck.Prop_EnablePurgeProtection = $vaultWithAllProps.EnablePurgeProtection
|
||||||
$resourceCheck.Prop_EnableRbacAuthorization = $vaultWithAllProps.EnableRbacAuthorization
|
$resourceCheck.Prop_EnableRbacAuthorization = $enabledRBAC
|
||||||
$resourceCheck.Prop_EnableSoftDelete = $vaultWithAllProps.EnableSoftDelete
|
$resourceCheck.Prop_EnableSoftDelete = $vaultWithAllProps.EnableSoftDelete
|
||||||
$resourceCheck.Prop_PublicNetworkAccess = $vaultWithAllProps.PublicNetworkAccess
|
$resourceCheck.Prop_PublicNetworkAccess = $vaultWithAllProps.PublicNetworkAccess
|
||||||
|
|
||||||
@@ -75,8 +91,8 @@ foreach ($subscription in $subscriptions)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$Result | Export-Csv -Path $fileName -Append -NoTypeInformation
|
$Result | Export-Csv -Path $fileName -Append -NoTypeInformation
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host "======================================================================================================================================================================"
|
Write-Host "======================================================================================================================================================================"
|
||||||
Write-Host "Done."
|
Write-Host "Done."
|
||||||
|
|
||||||
|
|||||||
1343
Powershell/Tools/Cleanup/MarkAndDeleteUnusedResources.ps1
Normal file
1343
Powershell/Tools/Cleanup/MarkAndDeleteUnusedResources.ps1
Normal file
File diff suppressed because it is too large
Load Diff
248
Powershell/Tools/Cleanup/RemoveTagsFromAllResourcesAndGroups.ps1
Normal file
248
Powershell/Tools/Cleanup/RemoveTagsFromAllResourcesAndGroups.ps1
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
This script removes all specified tags from all specified resources and resource
|
||||||
|
groups.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
This script removes all specified tags from all specified resources and resource
|
||||||
|
groups.
|
||||||
|
|
||||||
|
The default values for some parameters can be specified in a config file named
|
||||||
|
'Defaults.json'.
|
||||||
|
|
||||||
|
Project Link: https://github.com/thgossler/AzSaveMoney
|
||||||
|
Copyright (c) 2022 Thomas Gossler
|
||||||
|
License: MIT
|
||||||
|
|
||||||
|
.INPUTS
|
||||||
|
Azure resources/groups across all (or specified) subscriptions.
|
||||||
|
|
||||||
|
.NOTES
|
||||||
|
Warnings are suppressed by $WarningPreference='SilentlyContinue'.
|
||||||
|
#>
|
||||||
|
|
||||||
|
#Requires -Version 7
|
||||||
|
#Requires -Modules Az.Accounts
|
||||||
|
#Requires -Modules Az.ResourceGraph
|
||||||
|
#Requires -Modules Az.Resources
|
||||||
|
#Requires -Modules PowerShellGet
|
||||||
|
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# Configuration Settings
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
[CmdletBinding(SupportsShouldProcess)]
|
||||||
|
param (
|
||||||
|
# The ID of the Azure AD tenant. Can be set in defaults config file. Can be
|
||||||
|
# set in defaults config file.
|
||||||
|
[string]$DirectoryId,
|
||||||
|
|
||||||
|
# The Azure environment name (default: AzureCloud, for options call
|
||||||
|
# "(Get-AzEnvironment).Name"). Can be set in defaults config file.
|
||||||
|
[string]$AzEnvironment,
|
||||||
|
|
||||||
|
# The list of Azure subscription IDs to process. If empty all subscriptions
|
||||||
|
# will be processed (default: all). Can be set in defaults config file.
|
||||||
|
[System.Array]$SubscriptionIdsToProcess = @(),
|
||||||
|
|
||||||
|
# The list of names of the tags to be removed (default: all
|
||||||
|
# 'SubjectForDeletion...' tags). Can be set in defaults config file.
|
||||||
|
[System.Array]$TagNamesToRemove = @(
|
||||||
|
"SubjectForDeletion"
|
||||||
|
"SubjectForDeletion-FindingDate"
|
||||||
|
"SubjectForDeletion-Reason"
|
||||||
|
"SubjectForDeletion-Hint"
|
||||||
|
),
|
||||||
|
|
||||||
|
# Don't remove the tags from resources.
|
||||||
|
[switch]$DontRemoveFromResources = $false,
|
||||||
|
|
||||||
|
# Don't remove the tags from resource groups.
|
||||||
|
[switch]$DontRemoveFromResourceGroups = $false
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get configured defaults from config file
|
||||||
|
$defaultsConfig = (Test-Path -Path $PSScriptRoot/Defaults.json -PathType Leaf) ? (Get-Content -Path $PSScriptRoot/Defaults.json -Raw | ConvertFrom-Json) : @{}
|
||||||
|
|
||||||
|
if ([string]::IsNullOrWhiteSpace($DirectoryId) -and ![string]::IsNullOrWhiteSpace($defaultsConfig.DirectoryId)) {
|
||||||
|
$DirectoryId = $defaultsConfig.DirectoryId
|
||||||
|
}
|
||||||
|
if ([string]::IsNullOrWhiteSpace($AzEnvironment)) {
|
||||||
|
if (![string]::IsNullOrWhiteSpace($defaultsConfig.AzEnvironment)) {
|
||||||
|
$AzEnvironment = $defaultsConfig.AzEnvironment
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$AzEnvironment = 'AzureCloud'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($SubscriptionIdsToProcess.Count -lt 1 -and $defaultsConfig.SubscriptionIdsToProcess -and
|
||||||
|
($defaultsConfig.SubscriptionIdsToProcess -is [System.Array]) -and $defaultsConfig.SubscriptionIdsToProcess.Count -gt 0)
|
||||||
|
{
|
||||||
|
$SubscriptionIdsToProcess = $defaultsConfig.SubscriptionIdsToProcess
|
||||||
|
}
|
||||||
|
|
||||||
|
$tab = ' '
|
||||||
|
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# Execution
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
$WarningPreference = 'SilentlyContinue'
|
||||||
|
|
||||||
|
Clear-Host
|
||||||
|
|
||||||
|
$WhatIfHint = ""
|
||||||
|
$IsWhatIfMode = !$PSCmdlet.ShouldProcess("WhatIf mode", "Enable")
|
||||||
|
if ($IsWhatIfMode) {
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host " *** WhatIf mode (no changes are made) *** " -BackgroundColor DarkBlue -ForegroundColor White
|
||||||
|
$WhatIfHint = "What if: "
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!((Get-AzEnvironment).Name -contains $AzEnvironment)) {
|
||||||
|
Write-Error "Invalid Azure environment name '$AzEnvironment'"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$loggedIn = $false
|
||||||
|
if (![string]::IsNullOrWhiteSpace($DirectoryId)) {
|
||||||
|
$loggedIn = Connect-AzAccount -Environment $AzEnvironment -TenantId $DirectoryId -WhatIf:$false
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$loggedIn = Connect-AzAccount -Environment $AzEnvironment -WhatIf:$false
|
||||||
|
$DirectoryId = (Get-AzContext).Tenant.Id
|
||||||
|
}
|
||||||
|
if (!$loggedIn) {
|
||||||
|
Write-Error "Sign-in failed"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "$([Environment]::NewLine)Subscriptions to process:"
|
||||||
|
if ($null -ne $SubscriptionIdsToProcess -and $SubscriptionIdsToProcess.Count -gt 0) {
|
||||||
|
foreach ($s in $SubscriptionIdsToProcess) {
|
||||||
|
Write-Host "$($tab)$s"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host "all"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "$([System.Environment]::NewLine)Tags to remove:"
|
||||||
|
$TagNamesToRemove | ForEach-Object { Write-Host "$($tab)$_" }
|
||||||
|
|
||||||
|
$choice = Read-Host -Prompt "$([Environment]::NewLine)Remove all these tags? 'y' = yes, <Any> = no "
|
||||||
|
if ($choice -ine "y") {
|
||||||
|
Write-Host "Cancelled by user."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$DontRemoveFromResources) {
|
||||||
|
Write-Host "$([Environment]::NewLine)Searching matching resources..."
|
||||||
|
|
||||||
|
$query = "Resources | where "
|
||||||
|
if ($null -ne $SubscriptionIdsToProcess -and $SubscriptionIdsToProcess.Count -gt 0) {
|
||||||
|
$query += "("
|
||||||
|
$op = ""
|
||||||
|
foreach ($subscriptionId in $SubscriptionIdsToProcess) {
|
||||||
|
$query += "$op subscriptionId =~ '$subscriptionId'"
|
||||||
|
$op = " or "
|
||||||
|
}
|
||||||
|
$query += " ) and "
|
||||||
|
}
|
||||||
|
$op = ""
|
||||||
|
foreach ($tagName in $TagNamesToRemove) {
|
||||||
|
$query += "$op tags['$tagName'] != ''"
|
||||||
|
$op = " or "
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($VerbosePreference -eq $true) {
|
||||||
|
Write-Host "Query: $query" -ForegroundColor DarkGray
|
||||||
|
}
|
||||||
|
|
||||||
|
$resources = [System.Collections.ArrayList]@()
|
||||||
|
$skipToken = $null;
|
||||||
|
$queryResult = $null;
|
||||||
|
do {
|
||||||
|
if ($null -eq $skipToken) {
|
||||||
|
$queryResult = Search-AzGraph -Query $query
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$queryResult = Search-AzGraph -Query $query -SkipToken $skipToken
|
||||||
|
}
|
||||||
|
$skipToken = $queryResult.SkipToken;
|
||||||
|
$resources.AddRange($queryResult.Data) | Out-Null
|
||||||
|
} while ($null -ne $skipToken)
|
||||||
|
|
||||||
|
if ($resources.Count -gt 0) {
|
||||||
|
Write-Host "$($WhatIfHint)Removing tags from resources (subscriptionId / resourceGroupName / resourceName):"
|
||||||
|
$i = 0; $count = $resources.Count
|
||||||
|
foreach ($resource in $resources) {
|
||||||
|
$i += 1
|
||||||
|
Write-Host "$($tab)$($WhatIfHint)($i/$count) $($resource.subscriptionId) / $($resource.resourceGroup) / $($resource.name)..."
|
||||||
|
$tags = Get-AzTag -ResourceId $resource.id
|
||||||
|
if (!$tags.Properties.TagsProperty) { continue }
|
||||||
|
$tagsToRemove = [hashtable]@{}
|
||||||
|
foreach ($tagName in $TagNamesToRemove) {
|
||||||
|
$tagValue = $tags.Properties.TagsProperty[$tagName]
|
||||||
|
if (![string]::IsNullOrWhiteSpace($tagValue)) {
|
||||||
|
$tagsToRemove.Add($tagName, $tags.Properties.TagsProperty[$tagName]) | Out-Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($tagsToRemove.Keys.Count -gt 0 -and !$IsWhatIfMode) {
|
||||||
|
Update-AzTag -ResourceId $resource.id -Tag $tagsToRemove -Operation Delete -WhatIf:$WhatIfPreference | Out-Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host "No matching resources found."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$DontRemoveFromResourceGroups) {
|
||||||
|
Write-Host "$([Environment]::NewLine)Processing resource groups..."
|
||||||
|
|
||||||
|
$subscriptions = @(Get-AzSubscription -TenantId $DirectoryId -ErrorAction Stop | Where-Object -Property State -ne 'Disabled')
|
||||||
|
|
||||||
|
$s_i = 0; $s_count = $subscriptions.Count
|
||||||
|
foreach ($sub in $subscriptions) {
|
||||||
|
if ($null -ne $SubscriptionIdsToProcess -and $SubscriptionIdsToProcess.Count -gt 0 -and `
|
||||||
|
!$SubscriptionIdsToProcess.Contains($sub.Id))
|
||||||
|
{
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
$s_i += 1
|
||||||
|
Write-Host "$([Environment]::NewLine)($s_i/$s_count) Subscription '$($sub.Name)' ($($sub.SubscriptionId))..."
|
||||||
|
Set-AzContext -TenantId $DirectoryId -Subscription $sub.SubscriptionId -WhatIf:$false | Out-Null
|
||||||
|
$resourceGroups = [hashtable]@{}
|
||||||
|
foreach ($tagName in $TagNamesToRemove) {
|
||||||
|
Get-AzResourceGroup | Where-Object { $_.Tags.Keys -icontains $tagName } | ForEach-Object {
|
||||||
|
$rgName = $_.ResourceGroupName
|
||||||
|
$resourceGroups.$rgName = $_
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($resourceGroups.Count -eq 0) { continue }
|
||||||
|
Write-Host "$($WhatIfHint)Removing tags from resource groups (subscriptionId / resourceGroupName):"
|
||||||
|
$r_i = 0; $r_count = $resourceGroups.Keys.Count
|
||||||
|
foreach ($rgName in $resourceGroups.Keys) {
|
||||||
|
$r_i += 1
|
||||||
|
$rg = $resourceGroups[$rgName]
|
||||||
|
Write-Host "$($tab)$($WhatIfHint)($r_i/$r_count) $($sub.SubscriptionId) / $($rg.ResourceGroupName)..."
|
||||||
|
$tags = Get-AzTag -ResourceId $rg.ResourceId
|
||||||
|
if (!$tags.Properties.TagsProperty) { continue }
|
||||||
|
$tagsToRemove = [hashtable]@{}
|
||||||
|
foreach ($tagName in $TagNamesToRemove) {
|
||||||
|
$tagValue = $tags.Properties.TagsProperty[$tagName]
|
||||||
|
if ($null -ne $tagValue) {
|
||||||
|
$tagsToRemove.Add($tagName, $tags.Properties.TagsProperty[$tagName]) | Out-Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($tagsToRemove.Keys.Count -gt 0 -and !$IsWhatIfMode) {
|
||||||
|
Update-AzTag -ResourceId $rg.ResourceId -Tag $tagsToRemove -Operation Delete -WhatIf:$WhatIfPreference | Out-Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "$([Environment]::NewLine)Finished."
|
||||||
Reference in New Issue
Block a user