-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRun-AzFilesMigrator.ps1
374 lines (371 loc) · 17.4 KB
/
Run-AzFilesMigrator.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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
#region variables
$azcopyURI = "https://aka.ms/downloadazcopy-v10-windows"
$AzCopySetup = "C:\AzCopy\DL"
$AzCopyWPath = "C:\AzCopy\"
#endregion vatiables
#region functions
function Get-Option {
Write-Host "What would you like to do?"
Write-Host "1 - Perform Azure Files Migration"
Write-Host "2 - Select Azure Subscription"
Write-Host "3 - Download AzCopy"
Write-Host "4 - Adjust AZCOPY_CONCURRENCY_VALUE"
Write-Host "8 - Exit"
$o = Read-Host -Prompt 'Please type the number of the option you would like to perform '
return ($o.ToString()).Trim()
}
function Helper-AzSubscription {
param (
[parameter (Mandatory = $false)]
[switch]$whoami,
[parameter (Mandatory = $false)]
[switch]$select
)
if ($whoami) {
Write-Host "You are currently logged in as:" -BackgroundColor Black -ForegroundColor Green
Get-AzContext | ft Account, Name -AutoSize
}
if ($select) {
Write-Host "Please select the Azure subscription you would like to use:" -BackgroundColor Black -ForegroundColor Yellow
$sub = Get-AzSubscription | ogv -Title "Select Your Azure Subscription" -PassThru
Write-Host "Changing Azure Subscription to" $sub.Name "with the ID of" $sub.Id -BackgroundColor Black -ForegroundColor Yellow
Select-AzSubscription -SubscriptionId $sub.Id
}
}
Function Track-Time($Time) {
If (!($Time)) { Return Get-Date } Else {
Return ((get-date) - $Time)
}
}
function Get-AzCopyFromWeb {
New-Item -Path $AzCopySetup -ItemType Directory -Force
try {
Start-BitsTransfer -Source $azcopyURI -Destination "$AzCopySetup\azcopy_windows_amd64.zip"
}
catch {
Invoke-WebRequest -Uri $azcopyURI -OutFile "$AzCopySetup\azcopy_windows_amd64.zip"
}
Write-Host "Downloaded AzCopy to $AzCopySetup" -BackgroundColor Black -ForegroundColor Green
Write-Host "Expanding and cleaning up azcopy_windows_amd64.zip" -BackgroundColor Black -ForegroundColor Green
Expand-Archive "$AzCopySetup\azcopy_windows_amd64.zip" -DestinationPath "$AzCopyWPath" -ErrorAction SilentlyContinue
$ci = Get-ChildItem -Path $AzCopyWPath -Include *.exe, *.txt -File -Recurse
foreach ($file in $ci) { Copy-Item $file.FullName -Destination $AzCopyWPath }
Remove-Item "$AzCopySetup" -Force -Recurse
Remove-Item $ci.DirectoryName -Force -Recurse -ErrorAction SilentlyContinue
Write-Host "AzCopy Tool is located at" $AzCopyWPath -BackgroundColor Black -ForegroundColor Green
}
function Get-AzShareInfo {
param (
[parameter (Mandatory = $true)]
[array]$storageaccts,
[parameter (Mandatory = $false)]
[switch]$source,
[parameter (Mandatory = $false)]
[switch]$dest
)
[hashtable]$return = @{}
if ($source) { $L = "Source" }elseif ($dest) { $L = "Destination" }
Write-Host "Please select the $L storage account" -BackgroundColor Black -ForegroundColor Yellow
$stg = $storageaccts | ogv -Title "Select $L Storage Account" -PassThru
Write-Host "$L storage account is" $stg.StorageAccountName -BackgroundColor Black -ForegroundColor Green
Write-Host "Getting list of avaialble file shares in" $stg.StorageAccountName -BackgroundColor Black -ForegroundColor Green
$shares = Get-AzStorageShare -Context $stg.Context
Write-Host "Please Select the $L file share in" $stg.StorageAccountName -BackgroundColor Black -ForegroundColor Yellow
$share = $shares | ogv -Title "Select $L File Share" -PassThru
$return = @{"StorageAcctName" = $stg.StorageAccountName; "StorageAcctContext" = $stg.Context; "ShareName" = $share.Name }
return $return
}
function Get-AzShareSAS {
param (
[parameter (Mandatory = $true)]
[Microsoft.Azure.Commands.Common.Authentication.Abstractions.IStorageContext]$stgcontext,
[parameter (Mandatory = $true)]
[string]$sharename,
[parameter (Mandatory = $false)]
[switch]$source,
[parameter (Mandatory = $false)]
[switch]$dest
)
if ($source) { $perms = "rl" }elseif ($dest) { $perms = "rwl" }
$StartTime = Get-Date
$EndTime = $StartTime.AddHours(12.0)
$s = Get-AzStorageShare -Prefix $sharename -Context $stgcontext.Context | New-AzStorageShareSASToken -Permission $perms -StartTime $StartTime -ExpiryTime $EndTime
return $s
}
function Copy-AzFileDirectory {
param (
[parameter (Mandatory = $true)]
[string]$srcstgacctname,
[parameter (Mandatory = $true)]
[string]$srcsharename,
[parameter (Mandatory = $true)]
[string]$srcdirname,
[parameter (Mandatory = $true)]
[string]$srcSAS,
[parameter (Mandatory = $true)]
[string]$deststgacctname,
[parameter (Mandatory = $true)]
[string]$destsharename,
[parameter (Mandatory = $true)]
[string]$destdirname,
[parameter (Mandatory = $true)]
[string]$destSAS
)
$srcurl = "https://" + $srcstgacctname + ".file.core.windows.net/" + $srcsharename + "/" + $srcdirname + $srcSAS
$desturl = "https://" + $deststgacctname + ".file.core.windows.net/" + $destsharename + "/" + $destdirname + $destSAS
&$AzCopyWPath\azcopy.exe copy "$srcurl" "$desturl" --recursive --preserve-smb-permissions=true --preserve-smb-info=true --log-level=ERROR
}
function Get-CSVlistpath {
Add-Type -AssemblyName System.Windows.Forms
$FB = New-Object System.Windows.Forms.OpenFileDialog -Property @{
InitialDirectory = [Environment]::GetFolderPath('Desktop')
Filter = 'CSV File (*.csv)|*.csv'
Multiselect = $false
}
$null = $FB.ShowDialog()
return $FB.FileName
}
function Get-CSVlist {
param (
[parameter (Mandatory = $true)]
[string]$csvfilepath
)
$csv = Import-Csv -Path $csvfilepath -Header uid
Write-Host $csv.count"Items were imported from the CSV file provided" -BackgroundColor Black -ForegroundColor Green
return $csv
}
function Get-UIDShareMatches {
[CmdletBinding()]
param (
[parameter (Mandatory = $true)]
[array]$names,
[parameter (Mandatory = $true)]
[string]$share,
[parameter (Mandatory = $true)]
[Microsoft.Azure.Commands.Common.Authentication.Abstractions.IStorageContext]$stgcontext
)
$sfiles = Get-AzStorageFile -Context $stgcontext -ShareName $share
$ArrayList = New-Object -TypeName System.Collections.ArrayList
foreach ($n in $names) {
$a = $n.uid
$b = $sfiles | where { $_.Name -like "*$a*" }
if ($b -ne $null) {
Write-Host "$a has been matched to" $b.Name
$match = @{id = $a; dir = $b.Name }
$ArrayList += $match
}
else {
Write-Host "$a has not been matched to any directory"
}
}
return $ArrayList
}
function Set-AzCopyConcurrency {
param (
[parameter (Mandatory = $false)]
[switch]$on1k,
[parameter (Mandatory = $false)]
[switch]$on2k,
[parameter (Mandatory = $false)]
[switch]$on3k,
[parameter (Mandatory = $false)]
[switch]$off
)
if ($on1k) {
#set concurrency to 1000
Write-Host "Setting AZCOPY_CONCURRENCY_VALUE to 1000" -BackgroundColor Black -ForegroundColor Green
set AZCOPY_CONCURRENCY_VALUE=1000
}
if ($on2k) {
#set concurrency to 2000
Write-Host "Setting AZCOPY_CONCURRENCY_VALUE to 2000" -BackgroundColor Black -ForegroundColor Green
set AZCOPY_CONCURRENCY_VALUE=2000
}
if ($on3k) {
#set concurrency to 3000
Write-Host "Setting AZCOPY_CONCURRENCY_VALUE to 3000" -BackgroundColor Black -ForegroundColor Green
set AZCOPY_CONCURRENCY_VALUE=3000
}
if ($off) {
Write-Host "Getting CPU information to determine default value of AZCOPY_CONCURRENCY_VALUE" -BackgroundColor Black -ForegroundColor Green
$nlp = Get-ComputerInfo -Property CsProcessors
if ($nlp.CsProcessors.NumberOfLogicalProcessors -lt 5) {
set AZCOPY_CONCURRENCY_VALUE=32
}
else {
$c = $nlp.CsProcessors.NumberOfLogicalProcessors * 16
if ($c -gt 3000) {
$c = 3000
Write-Host "Setting AZCOPY_CONCURRENCY_VALUE to" $c -BackgroundColor Black -ForegroundColor Green
set AZCOPY_CONCURRENCY_VALUE=$c
}
else {
Write-Host "Setting AZCOPY_CONCURRENCY_VALUE to" $c -BackgroundColor Black -ForegroundColor Green
set AZCOPY_CONCURRENCY_VALUE=$c
}
}
}
}
function Invoke-Option {
param (
[parameter (Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[ValidateLength(1, 1)]
[string]$userSelection
)
if ($userSelection -eq "1") {
#1 - Perform Azure Files Migration
if ((Test-Path $AzCopyWPath\azcopy.exe -PathType Leaf) -eq $false) {
Write-Host "AzCopy is not found at" $AzCopyWPath -BackgroundColor Black -ForegroundColor Red
$hv = Read-Host -Prompt "Would you like to download the latest AzCopy Tool on $env:computername ? (y/n)"
if ($hv.Trim().ToLower() -eq "y") {
Write-Host "Downloading the latest AzCopy Tool from $azcopyURI" -BackgroundColor Black -ForegroundColor Green
Get-AzCopyFromWeb
}
elseif ($hv.Trim().ToLower() -eq "n") {
Write-Host "AzCopy Tool is required to properly package MSIX apps" -BackgroundColor Black -ForegroundColor Red
Write-Host "Exiting migration, please download latest tooling to proceed further" -BackgroundColor Black -ForegroundColor Yellow
Invoke-Option -userSelection (Get-Option)
}
else {
Write-Host "Invalid option entered" -BackgroundColor Black -ForegroundColor Red
Invoke-Option -userSelection (Get-Option)
}
}
Write-Host "Getting list of available storage accounts" -BackgroundColor Black -ForegroundColor Green
$stgaccts = Get-AzStorageAccount
Write-Host $stgaccts.Count "storage accounts found" -BackgroundColor Black -ForegroundColor Green
$sv = Read-Host -Prompt "Would you like to see only storage accounts with AD integration enabled? (y/n)"
if ($sv.Trim().ToLower() -eq "y") {
Write-host "Filtering storage accounts for those with AD integration enabled" -BackgroundColor Black -ForegroundColor Green
$stgaccts = $stgaccts | where { $_.AzureFilesIdentityBasedAuth -ne $null }
Write-Host $stgaccts.Count "storage accounts found with AD integration enabled" -BackgroundColor Black -ForegroundColor Green
}
else {
Write-Host "Using full list of available storage accounts" -BackgroundColor Black -ForegroundColor Green
}
$sinfo = Get-AzShareInfo -storageaccts $stgaccts -source
$dinfo = Get-AzShareInfo -storageaccts $stgaccts -dest
#Output information to user about the storage account and share selected
Write-Host "You have selected the following Storage Accounts and File Shares to use" -BackgroundColor Black -ForegroundColor Green
Write-Host "-----Source-----" -BackgroundColor Black -ForegroundColor Green
Write-Host "Source Storage Account" $sinfo.StorageAcctName -BackgroundColor Black -ForegroundColor Green
Write-Host "Source File Share" $sinfo.ShareName -BackgroundColor Black -ForegroundColor Green
Write-Host "-----Destination-----" -BackgroundColor Black -ForegroundColor Green
Write-Host "Destination Storage Account" $dinfo.StorageAcctName -BackgroundColor Black -ForegroundColor Green
Write-Host "Destination File Share" $dinfo.ShareName -BackgroundColor Black -ForegroundColor Green
#Perform check on source and destination variables to ensure they are not null
if (($sinfo.StorageAcctName -eq $null) -or ($sinfo.ShareName -eq $null) -or ($dinfo.StorageAcctName -eq $null) -or ($dinfo.ShareName -eq $null)) {
Write-Host "One or more selections was empty/null"
Write-Host "Restarting Selection Process"
Invoke-Option -userSelection 1
}
#Confirm with user that information is correct
$sv = Read-Host -Prompt "Is this selection correct? (y/n)"
if ($sv.Trim().ToLower() -eq "n") {
Write-Host "Restarting Selection Process"
Invoke-Option -userSelection 1
}
Write-Host "Generating SAS Token for source and destination shares" -BackgroundColor Black -ForegroundColor Green
$ssas = Get-AzShareSAS -stgcontext $sinfo.StorageAcctContext -sharename $sinfo.ShareName -source
$dsas = Get-AzShareSAS -stgcontext $dinfo.StorageAcctContext -sharename $dinfo.ShareName -dest
#Ask if moving indivual folder or using a folder list with .csv extension
Write-Host "What would you like to do?" -BackgroundColor Black -ForegroundColor Yellow
Write-Host "1 - Copy a single directory"
Write-Host "2 - Copy multiple directories using a CSV"
$op = Read-Host -Prompt 'Please type the number of the option you would like to perform '
if ($op.Trim().ToLower() -eq "1") {
Write-Host "You have selected option 1" -BackgroundColor Black -ForegroundColor Green
Write-Host "Please enter the source folder to copy" -BackgroundColor Black -ForegroundColor Yellow
$srcdir = Read-Host -Prompt 'Please provide the name of the source directory to copy'
$srcdir = $srcdir.Trim()
Copy-AzFileDirectory -srcstgacct $sinfo.StorageAcctName -srcshare $sinfo.ShareName -srcdirname $srcdir -srcSAS $ssas -deststgacct $dinfo.StorageAcctName -destshare $dinfo.ShareName -destdirname $srcdir -destSAS $dsas
Invoke-Option -userSelection (Get-Option)
}
elseif ($op.Trim().ToLower() -eq "2") {
Write-Host "You have selected option 2" -BackgroundColor Black -ForegroundColor Green
Write-Host "Please provide the CSV to use" -BackgroundColor Black -ForegroundColor Yellow
$cfp = Get-CSVlistpath
$cl = Get-CSVlist -csvfilepath $cfp
$sm = Get-UIDShareMatches -names $cl -share $sinfo.ShareName -stgcontext $sinfo.StorageAcctContext
#Ask user to confim the folder list then copy the files
$fv = Read-Host -Prompt "Is this selection correct? (y/n)"
if ($fv.Trim().ToLower() -eq "y") {
$i = 0
$time = Track-Time $time
foreach ($s in $sm) {
Write-Host "Processing"+$s.id+"with the directory of"$s.dir -BackgroundColor Black -ForegroundColor Green
Copy-AzFileDirectory -srcstgacct $sinfo.StorageAcctName -srcshare $sinfo.ShareName -srcdirname $s.dir -srcSAS $ssas -deststgacct $dinfo.StorageAcctName -destshare $dinfo.ShareName -destdirname $s.dir -destSAS $dsas
$i++
}
$time = Track-Time $time
Write-Host "Processing complete for $i directories" -BackgroundColor Black -ForegroundColor Green
Write-Host "Processing time: " $time.Minutes "minutes" $time.Seconds "seconds" -BackgroundColor Black -ForegroundColor Green
}
else {
Write-Host "Restarting Selection Process"
Invoke-Option -userSelection 1
}
Invoke-Option -userSelection (Get-Option)
}
else {
Write-Host "Invalid option entered" -BackgroundColor Black -ForegroundColor Red
Invoke-Option -userSelection (Get-Option)
}
}
elseif ($userSelection -eq "2") {
#2 - Select Azure Subscription
Helper-AzSubscription -whoami
Helper-AzSubscription -select
Invoke-Option -userSelection (Get-Option)
}
elseif ($userSelection -eq "3") {
#3 - Download AzCopy
Get-AzCopyFromWeb
Invoke-Option -userSelection (Get-Option)
}
elseif ($userSelection -eq "4") {
#4 - Adjust AZCOPY_CONCURRENCY_VALUE
Write-Host "Please select the value for AZCOPY_CONCURRENCY_VALUE" -BackgroundColor Black -ForegroundColor Yellow
Write-Host "1 - Set to 1000"
Write-Host "2 - Set to 2000"
Write-Host "3 - Set to 3000"
Write-Host "4 - Set to default value based on CPU"
$acv = Read-Host -Prompt 'Please type the number for the corresponding option'
if ($acv.Trim().ToLower() -eq "1") {
Set-AzCopyConcurrency -on1k
}
elseif ($acv.Trim().ToLower() -eq "2") {
Set-AzCopyConcurrency -on2k
}
elseif ($acv.Trim().ToLower() -eq "3") {
Set-AzCopyConcurrency -on3k
}
elseif ($acv.Trim().ToLower() -eq "4") {
Set-AzCopyConcurrency -off
}
else {
Write-Host "Invalid option entered" -BackgroundColor Black -ForegroundColor Red
}
Invoke-Option -userSelection (Get-Option)
}
elseif ($userSelection -eq "8") {
#8 -Exit
break
}
else {
Write-Host "You have selected an invalid option please select again." -ForegroundColor Red -BackgroundColor Black
Invoke-Option -userSelection (Get-Option)
}
}
#endregion functions
#region main
Write-Host "Welcome to the Azure Files Migrator Script"
try {
Invoke-Option -userSelection (Get-Option)
}
catch {
Write-Host "Something went wrong" -ForegroundColor Yellow -BackgroundColor Black
Invoke-Option -userSelection (Get-Option)
}
#endregion main