-
Notifications
You must be signed in to change notification settings - Fork 65
/
Copy pathBackup-AzureRMvm.ps1
222 lines (155 loc) · 6.78 KB
/
Backup-AzureRMvm.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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
<#
.SYNOPSIS
Copies VHD blobs attached to each VM in a resource group to a designated backup container.
Does not work with VMs configured with managed disks because they allow snapshots.
Requires AzureRM module version 4.2.1 or later.
.DESCRIPTION
Copies VHD blobs from each VM in a resource group to the vhd-backups container or other container name
specified in the -BackupContainer parameter
VMs must be shutdown prior to running this script. It will halt if they are still running.
.EXAMPLE
.\Backup-AzureRMvm.ps1 -ResourceGroupName 'CONTOSO'
.EXAMPLE
.\Backup-AzureRMvm.ps1 -ResourceGroupName 'CONTOSO' -BackupContainer 'vhd-backups-9021'
.PARAMETER -ResourceGroupName [string]
Name of resource group being copied
.PARAMETER -BackupContainer [string]
Name of container that will hold the backup VHD blobs
.PARAMETER -Environment [string]
Name of Environment e.g. AzureUSGovernment. Defaults to AzureCloud
.NOTES
Original Author: https://github.com/JeffBow
------------------------------------------------------------------------
Copyright (C) 2017 Microsoft Corporation
You have a royalty-free right to use, modify, reproduce and distribute
this sample script (and/or any modified version) in any way
you find useful, provided that you agree that Microsoft has no warranty,
obligations or liability for any sample application or script files.
------------------------------------------------------------------------
#>
#Requires -Version 4.0
param(
[Parameter(Mandatory=$true)]
[string]$ResourceGroupName,
[Parameter(Mandatory=$false)]
[string]$BackupContainer= 'vhd-backups',
[Parameter(Mandatory=$false)]
[string]$Environment= "AzureCloud"
)
$ProgressPreference = 'SilentlyContinue'
import-module AzureRM
if ((Get-Module AzureRM).Version -lt "4.2.1") {
Write-warning "Old version of Azure PowerShell module $((Get-Module AzureRM).Version.ToString()) detected. Minimum of 4.2.1 required. Run Update-Module AzureRM"
BREAK
}
<###############################
Get Storage Context function
################################>
function Get-StorageObject
{ param($resourceGroupName, $srcURI)
$split = $srcURI.Split('/')
$strgDNS = $split[2]
$splitDNS = $strgDNS.Split('.')
$storageAccountName = $splitDNS[0]
$StorageAccountKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $resourceGroupName -Name $StorageAccountName).Value[0]
$StorageContext = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey
return $StorageContext
} # end of Get-StorageObject function
<###############################
Copy blob function
################################>
function copy-azureBlob
{ param($srcUri, $srcContext, $destContext, $containerName)
$split = $srcURI.Split('/')
$blobName = $split[($split.count -1)]
$blobSplit = $blobName.Split('.')
$extension = $blobSplit[($blobSplit.count -1)]
if($($extension.tolower()) -eq 'status' ){Write-Output "Status file blob $blobname skipped";return}
if(! $containerName){$containerName = $split[3]}
# add full path back to blobname
if($split.count -gt 5)
{
$i = 4
do
{
$path = $path + "/" + $split[$i]
$i++
}
while($i -lt $split.length -1)
$blobName= $path + '/' + $blobName
$blobName = $blobName.Trim()
$blobName = $blobName.Substring(1, $blobName.Length-1)
}
# create container if doesn't exist
if (!(Get-AzureStorageContainer -Context $destContext -Name $containerName -ea SilentlyContinue))
{
try
{
$newRtn = New-AzureStorageContainer -Context $destContext -Name $containerName -Permission Off -ea Stop
Write-Output "Container $($newRtn.name) was created."
}
catch
{
$_ ; break
}
}
try
{
$blobCopy = Start-AzureStorageBlobCopy `
-srcUri $srcUri `
-SrcContext $srcContext `
-DestContainer $containerName `
-DestBlob $blobName `
-DestContext $destContext `
-Force -ea Stop
write-output "$srcUri is being copied to $containerName"
}
catch
{
$_ ; write-warning "Failed to copy to $srcUri to $containerName"
}
} # end of copy-azureBlob function
# get Azure creds
write-host "Enter credentials for your Azure Subscription..." -F Yellow
$login= Connect-AzureRmAccount -EnvironmentName $Environment
$loginID = $login.context.account.id
$sub = Get-AzureRmSubscription
$SubscriptionId = $sub.Id
# check for multiple subs under same account and force user to pick one
if($sub.count -gt 1)
{
$SubscriptionId = (Get-AzureRmSubscription | select * | Out-GridView -title "Select Target Subscription" -OutputMode Single).Id
Select-AzureRmSubscription -SubscriptionId $SubscriptionId| Out-Null
$sub = Get-AzureRmSubscription -SubscriptionId $SubscriptionId
$SubscriptionId = $sub.Id
}
# check for valid sub
if(! $SubscriptionId)
{
write-warning "The provided credentials failed to authenticate or are not associcated to a valid subscription. Exiting the script."
break
}
write-verbose "Logged into $($sub.Name) with subscriptionID $SubscriptionId as $loginID" -verbose
$resourceGroupVMs = Get-AzureRMVM -ResourceGroupName $resourceGroupName
if(! $resourceGroupVMs){write-warning "No virtual machines found in resource group $resourceGroupName"; break}
$resourceGroupVMs | %{
$status = ((get-azurermvm -ResourceGroupName $resourceGroupName -Name $_.name -status).Statuses|where{$_.Code -like 'PowerState*'}).DisplayStatus
write-output "$($_.name) status is $status"
if($status -eq 'VM running'){write-warning "All virtual machines in this resource group are not stopped. Please stop all VMs and try again"; break}
}
foreach($vm in $resourceGroupVMs)
{
# get storage account name from VM.URI
$vmURI = $vm.storageprofile.osdisk.vhd.uri
$context = Get-StorageObject -resourceGroupName $resourceGroupName -srcURI $vmURI
copy-azureBlob -srcUri $vmURI -srcContext $context -destContext $context -containerName $backupContainer
if($vm.storageProfile.datadisks)
{
foreach($disk in $vm.storageProfile.datadisks)
{
$diskURI = $disk.vhd.uri
$context = Get-StorageObject -resourceGroupName $resourceGroupName -srcURI $diskURI
copy-azureBlob -srcUri $diskURI -srcContext $context -destContext $context -containerName $backupContainer
}
}
}