-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRemove-AzureVMBackup.ps1
205 lines (175 loc) · 7.22 KB
/
Remove-AzureVMBackup.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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
<#
.Synopsis
Given a VM OS disk backed up by the Backup-AzureVM.ps1 script, purge the old backups before the last N given. This scripts
assumes the backups are stored on the storage account pointed by the current subscription's CurrentStorageAccount property
.DESCRIPTION
Purge the old backups of a given VM, with one single disk. Any previous backups, before the last N, being used by a VM are skipped.
OlderThanDays and KeepLast are mutually exclusive parameters.
.EXAMPLE
For removing the last 5 backups of a given VM on a service:
.\Remove-AzureVMBackup -ServiceName aService -Name aVm -KeepLast 5
Removing all of the backups:
.\Remove-AzureVMBackup -ServiceName aService -Name aVm -KeepLast 0
Removing older than 3 days worth of backups
.\Remove-AzureVMBackup -ServiceName aService -Name aVm -OlderThanDays 0
.INPUTS
None
.OUTPUTS
None
#>
Param
(
# Service the VM is running on
[Parameter(Mandatory=$true)]
[String]
$ServiceName,
# Name of the VM
[Parameter(Mandatory=$true)]
[String]
$Name,
# Name of the container where the backups are kept
[Parameter(Mandatory=$false)]
[String]
$ContainerName = "vhds",
# Last N backups to keep
[Parameter(Mandatory=$true, ParameterSetName='KeepLast')]
[String]
$KeepLast,
# Last N days of backup to keep, and remove older ones
[Parameter(Mandatory=$true, ParameterSetName='OlderThanDays')]
[String]
$OlderThanDays
)
# The script has been tested on Powershell 3.0
Set-StrictMode -Version 3
# Following modifies the Write-Verbose behavior to turn the messages on globally for this session
$VerbosePreference = "Continue"
# Check if Windows Azure Powershell is avaiable
if ((Get-Module -ListAvailable Azure) -eq $null)
{
throw "Windows Azure Powershell not found! Please install from http://www.windowsazure.com/en-us/downloads/#cmd-line-tools"
}
$backupNamePrefix = "_b_"
$diskDelimeter = "_d_"
$existingBackups = Get-AzureStorageBlob -Container $ContainerName |
Where-Object {$_.Name -match $(".*" + $ServiceName + "-" + $Name + $backupNamePrefix + "[0-9][0-9]" + $diskDelimeter + "[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{4}\.vhd$")} |
Select-Object Name
$foundBackups = @{}
if($existingBackups -ne $null)
{
foreach ($existingBackup in $existingBackups)
{
$parts = $existingBackup.Name -split $backupNamePrefix
if ($parts.Count -ne 2)
{
throw "Unexpected backup format for blob name $existingBackup"
}
$backupPart = ""
$vmParts = $parts[0] -split "-"
if ($parts[1].Endswith(".vhd"))
{
$backupPart = $parts[1].Substring(0, $parts[1].Length - 4)
}
else
{
$backupPart = $parts[1]
}
$backupParts = $backupPart -split $diskDelimeter
if ($backupParts.Count -ne 2)
{
throw "The backup name does not conform to the naming convention."
}
$diskNumber = $backupParts[0]
$backupParts = $backupParts[1] -split "-"
if ($vmParts.Count -ne 2 -and $backupParts.Count -ne 4)
{
throw "The backup name does not conform to the naming convention."
}
$objBackup = New-Object System.Object
$objBackup | Add-Member -type NoteProperty -name ServiceName -value $vmParts[0]
$objBackup | Add-Member -type NoteProperty -name VmName -value $vmParts[1]
$objBackup | Add-Member -type NoteProperty -name BackupDate -value $($backupParts[0] + "-" + $backupParts[1] + "-" + $backupParts[2])
$objBackup | Add-Member -type NoteProperty -name BackupNumber -value $backupParts[3]
$objBackup | Add-Member -type NoteProperty -name BlobName -value $existingBackup.Name
$objBackup | Add-Member -type NoteProperty -name BackupId -value ([Int64]$($backupParts[0] + $backupParts[1] + $backupParts[2] + $backupParts[3]))
if (!$foundBackups.ContainsKey($objBackup.BackupId))
{
# Initialize the disk array for the found backup
$foundBackups.Add($objBackup.BackupId, @())
}
$foundBackups[$objBackup.BackupId] += $objBackup
}
}
$existingVmDisks = Get-AzureDisk
if ($PSCmdlet.ParameterSetName -eq "KeepLast")
{
$index = 1
$foundBackupIds = @($foundBackups.Keys | Sort-Object -Descending)
if ($foundBackupIds -eq $null -or $foundBackupIds.Length -le $KeepLast)
{
Write-Warning "No backups found to remove."
}
else
{
foreach ($foundBackupId in $foundBackupIds)
{
if ($index++ -gt $KeepLast)
{
$backupVhds = $foundBackups[$foundBackupId]
foreach ($backupVhd in $backupVhds)
{
$existingDisk = $existingVmDisks | Where-Object {$_.MediaLink -match $(".*" + $backupVhd.BlobName + "$")}
if ($existingDisk -ne $null -and $existingDisk.AttachedTo -eq $null)
{
Remove-AzureDisk -DiskName $existingDisk.DiskName
Write-Verbose "Removed a disk using the backup blob."
}
if ($existingDisk -eq $null)
{
Remove-AzureStorageBlob -Container $containerName -Blob $backupVhd.BlobName
Write-Verbose "Removed $backupVhd.BlobName"
}
else
{
Write-Warning "Found disk attached to a VM. DiskName: $existingDisk.DiskName, not removing the blob $backupVhd.BlobName"
}
}
}
}
}
}
else
{
# Remove the backups older than N days
$lastDayToKeep = ([Int64](Get-Date $((Get-Date).AddDays(-1 * ($OlderThanDays - 1))) -Format "yyyyMMdd")) * 10000
$foundBackupIds = @($foundBackups.Keys | Where-Object {$_ -lt $lastDayToKeep})
if ($foundBackupIds -eq $null -or $foundBackupIds.Length -eq 0)
{
Write-Warning "No backups found to remove."
}
else
{
foreach ($foundBackupId in $foundBackupIds)
{
$backupVhds = $foundBackups[$foundBackupId]
foreach ($backupVhd in $backupVhds)
{
$existingDisk = $existingVmDisks | Where-Object {$_.MediaLink -match $(".*" + $backupVhd.BlobName + "$")}
if ($existingDisk -ne $null -and $existingDisk.AttachedTo -eq $null)
{
Remove-AzureDisk -DiskName $existingDisk.DiskName
Write-Verbose "Removed a disk using the backup blob."
$existingDisk = $null
}
if ($existingDisk -eq $null)
{
Remove-AzureStorageBlob -Container $containerName -Blob $backupVhd.BlobName
}
else
{
Write-Warning "Found disk attached to a VM. DiskName: $existingDisk.DiskName, not removing the blob $backupVhd.BlobName"
}
}
}
}
}