-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathReplace-AzTag.ps1
179 lines (152 loc) · 6.49 KB
/
Replace-AzTag.ps1
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#Requires -module Logging, Az.Accounts
<#
.SYNOPSIS
Script for tag keys consolidation
.DESCRIPTION
You need to provide a list of tags to replace and a correct tag name. Script will replace all incorrect tags with correct one.
.NOTES
Dependencies: Logging, Az.Accounts
Do not forget to specify the list of tag keys to replace and correct tag name!
Version: 1.2.0
.LINK
https://github.com/aslan-im/Replace-AzTag
.EXAMPLE
.\Replace-AzTag.ps1
#>
#region CommonVariables
$WorkingDirectory = Switch ($Host.name) {
'Visual Studio Code Host' {
split-path $psEditor.GetEditorContext().CurrentFile.Path
}
'Windows PowerShell ISE Host' {
Split-Path -Path $psISE.CurrentFile.FullPath
}
'ConsoleHost' {
$PSScriptRoot
}
}
$CurrentDate = Get-Date
$ScriptErrors = @()
$ScriptWarnings = @()
$TagsToReplace = @(
"Created By"
)
$CorrectTag = "CreatedBy"
#endregion
#region Logging Configuration
$LogFilePath = "$WorkingDirectory\logs\log_$($CorrectTag -replace ' ', '_')_$($CurrentDate.ToString("yyyy-MM-dd")).log"
$ErrorsLogFilePath = "$WorkingDirectory\logs\errors_$($CorrectTag -replace ' ', '_')_$($CurrentDate.ToString("yyyy-MM-dd")).log"
$WarningsLogFilePath = "$WorkingDirectory\logs\warnings_$($CorrectTag -replace ' ', '_')_$($CurrentDate.ToString("yyyy-MM-dd")).log"
Set-LoggingDefaultLevel -Level 'Info'
Add-LoggingTarget -Name File -Configuration @{
Path = $LogFilePath
PrintBody = $false
Append = $true
Encoding = 'ascii'
}
Add-LoggingTarget -Name Console -Configuration @{}
#endregion
Write-Log "Checking current Az Connection"
$Context = Get-AzContext
if($Context){
Write-Log "Connection to $($Context)"
}
else{
Write-Log "No connection found, connecting to Azure"
Connect-AzAccount
}
Write-Log "Getting subscription list"
$Subscriptions = Get-AzSubscription
Write-Log "Working with tags"
Write-Log "Tags to replace: $($TagsToReplace -join ', ') `nCorrect tag: $CorrectTag"
#region Counters
$TagsToReplaceCount = $TagsToReplace.count
$TagsCounter = 1
#endregion
foreach($TagToReplace in $TagsToReplace){
$TagsPercent = $TagsCounter / $TagsToReplaceCount * 100
$TagsProgressSplat = @{
Activity = "Checking Tags"
PercentComplete = $TagsPercent
Id = 1
Status = "[$TagsCounter/$TagsToReplaceCount] Checking '$TagToReplace' tag..."
}
Write-Progress @TagsProgressSplat
Write-Log "Working with tag '$TagToReplace'"
if ($TagToReplace -eq $CorrectTag){
Write-Log "Tag is correct, skipping"
continue
}
$SubsCount = $Subscriptions.count
$SubsCounter = 1
foreach($Subscription in $Subscriptions){
$SubsPercent = $SubsCounter / $SubsCount * 100
$SubsProgressSplat = @{
Activity = "Checking '$TagToReplace' ==> '$CorrectTag' in '$($Subscription.name)' subscription"
PercentComplete = $SubsPercent
Id = 2
Status = "[$SubsCounter/$SubsCount] Checking '$($Subscription.name)' subscription..."
}
Write-Progress @SubsProgressSplat
Write-Log "Working with subscription '$($Subscription.Name)'"
$Subscription | Set-AzContext
$Resources = Get-AzResource -TagName $TagToReplace
Write-Log "Found $($Resources.count) resources with tag '$TagToReplace'"
$ResourcesCount = $Resources.count
$ResourcesCounter = 1
if($ResourcesCount -gt 0){
foreach($Resource in $Resources){
$ResourcesPercent = $ResourcesCounter / $ResourcesCount * 100
$ResourcesProgressSplat = @{
Activity = "Working with resources in '$($Subscription.name)' subscription"
PercentComplete = $ResourcesPercent
Id = 3
Status = "[$ResourcesCounter/$ResourcesCount] Checking '$($Resource.ResourceId)' resource ID..."
}
Write-Progress @ResourcesProgressSplat
Write-Log "Resource: $($Resource.ResourceId)"
$ResourceTags = $Resource.Tags
Write-Log "Resource tags: $($ResourceTags | Out-String)"
if($ResourceTags.Keys -ccontains $TagToReplace){
if($ResourceTags.Keys -notcontains $CorrectTag){
$TagToReplaceValue = $ResourceTags[$TagToReplace]
Write-Log "Tag value: $TagToReplaceValue"
Write-Log "Removing incorrect tag: '$TagToReplace'"
$ResourceTags.Remove($TagToReplace)
Write-Log "Adding correct tag: '$CorrectTag'"
$ResourceTags.Add($CorrectTag, $TagToReplaceValue)
try{
Write-Log "Updating resource tags"
Set-AzResource -ResourceId $Resource.ResourceId -Tag $ResourceTags -Force -ErrorAction "STOP" | Out-Null
Write-Log "Tag replaced"
$NewResourceTags = Get-AzResource -ResourceId $Resource.ResourceId | Select-object Tags
Write-Log "Tags after update:`n$($NewResourceTags.Tags | Out-String)"
}
catch{
Write-Log "Error replacing tag $TagToReplace on $($Resource.ResourceId): $($_.Exception.Message)" -Level Error
"Error replacing tag $TagToReplace on $($Resource.ResourceId): $($_.Exception.Message)" | Out-File $ErrorsLogFilePath -Append
}
}
else{
Write-Log "Tag '$CorrectTag' already exists, skipping" -level Warning
"Tag '$CorrectTag' already exists. Skipping: $($Resource.ResourceId)" | Out-File $WarningsLogFilePath -Append
}
}
else{
Write-Log "Tag key case is not the same. Skipping!" -Level Warning
"Tag key case is not the same ['$CorrectTag']. Skipping! `n Resource tags: $($ResourceTags | Out-String)" | Out-File $WarningsLogFilePath -Append
continue
}
$ResourceTags = $null
$TagToReplaceValue = $null
$ResourcesCounter++
}
}
else{
Write-Log "No resources found with tag '$TagToReplace'"
}
$SubsCounter++
}
$TagsCounter++
}
Write-Log "Completed!"