forked from LearnVisualStudio/HeroVsRobot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
New-AzureWebsiteEnv.ps1
435 lines (341 loc) · 17.9 KB
/
New-AzureWebsiteEnv.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
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
<#
.SYNOPSIS
Creates the environment for a Windows Azure web site, including the
databases and storage that the website requires.
.DESCRIPTION
The New-AzureWebsiteEnv.ps1 script automates the process of
creating a Windows Azure web site and its environment, including
a storage account for blobs and queues, a SQL Database server,
an application database, and a membership database.
This script also adds environment variables ("AppSettings") and
connection strings that allow the web site to access the storage
account and databases.
New-AzureWebsiteEnv.ps1 requires that Windows Azure PowerShell
be installed and configured to work with your Windows Azure
subscription. For details, see "How to install and configure
Windows Azure PowerShell" at
http://go.microsoft.com/fwlink/?LinkID=320552.
It also calls two helper scripts, New-AzureSql.ps1 and
New-AzureStorage.ps1, which must be in the same directory
as this script.
Finally, the script createes the website-environment.xml
file for the website deployment script and the <Website_Name>.pubxml
file that Windows Azure needs to deploy the website. It
saves these files in the script directory.
.PARAMETER Name
Specifies the name of the web site. Web site names must be
unique in the azurewebsites.net domain. Enter an alphanumber string.
The name is case-insensitive and is also used to name resources
that are related to the website, such as the storage account.
This parameter is required.
.PARAMETER Location
Specifies a Windows Azure location. The location must support web
sites. The default value is "West US".
Valid values:
-- East Asia
-- East US
-- North Central US
-- North Europe
-- West Europe
-- West US
.PARAMETER SqlDatabaseUserName
Specify a user name for the SQL database that the script
creates for the web site. The script creates one user with
a user name and password. The default value is "dbuser".
.PARAMETER SqlDatabasePassword
Specify a password for the SQL database user account that the
script creates. This parameter is required by the helper script
that creates the database. If you omit this parameter, you'll be
prompted for a password when database script is called.
.PARAMETER StartIPAddress
The starting address of the range of IP addresses in the SQL
Azure firewall rule. If you omit this parameter, the script
creates an IP address range from the public IP address of the
local machine.
.PARAMETER EndIPAddress
The last address of the range of IP addresses in the SQL
Azure firewall rule. If you omit this parameter, the script
creates an IP address range from the public IP address of the
local machine.
.INPUTS
System.String
.OUTPUTS
.NOTES
This script sets the $VerbosePreference variable to "Continue", so all
Verbose messages are displayed without using the Verbose common parameter.
It also sets the $ErrorActionPreference variable to "Stop" which stops the
script when it generates non-terminating errors.
This script calls the following helper scripts and expects them to be in
the same directory:
-- New-AzureSql.ps1
-- New-AzureStorage.ps1
.EXAMPLE
New-AzureWebsiteEnv.ps1 -Name ContosoTesting -SqlDatabasePassword P@ssw0rd
.EXAMPLE
New-AzureWebsiteEnv.ps1 -Name TestSite -Location "West Europe" -SqlDatabaseUserName AdminUser `
-SqlDatabasePassword P@ssw0rd -StartIpAddress 216.142.28.0 -EndIPAddress 216.142.28.255
.LINK
New-AzureWebsite
.LINK
Set-AzureWebsite
.LINK
New-AzureSql.ps1
.LINK
New-AzureStorage.ps1
.LINK
Windows Azure Management Cmdlets (http://go.microsoft.com/fwlink/?LinkID=386337)
.LINK
How to install and configure Windows Azure PowerShell (http://go.microsoft.com/fwlink/?LinkID=320552)
#>
[CmdletBinding(PositionalBinding=$True)]
Param(
[Parameter(Mandatory = $true)]
[ValidatePattern("^[a-z0-9]*$")]
[String]$Name, # required needs to be alphanumeric
[String]$Location = "West US", # optional default to "West US", needs to be a location which all the services created here are available
[String]$SqlDatabaseUserName = "dbuser", # optional default to "dbuser"
[String]$SqlDatabasePassword, # optional optional, but required by a helper script. Set the value here or the helper script prompts you.
[String]$StartIPAddress, # optional start IP address of the range you want to whitelist in SQL Azure firewall will try to detect if not specified
[String]$EndIPAddress # optional end IP address of the range you want to whitelist in SQL Azure firewall will try to detect if not specified
)
# Begin - Helper functions --------------------------------------------------------------------------------------------------------------------------
<#
.SYNOPSIS
Creates an environment xml file to deploy the website.
.DESCRIPTION
The New-EnvironmentXml function creates and saves
to disk a website-environment.xml file. Windows Azure
requires this file to deploy a website.
New-EnvironmentXml requires a website-environment.template
file in the script directory. This file is packaged with
the New-AzureWebsiteEnv.ps1 script. If the template file
is missing, the function will fail.
This function is designed as a helper function for
the New-AzureWebsiteEnv.ps1 script.
.PARAMETER EnvironmentName
Specifies a name for the website environment. Enter
an alphanumic string. It's helpful when the name
of the environment is related to the website name.
New-AzureWebsiteEnv.ps1 uses the website name
as the value of this parameter.
.PARAMETER WebsiteName
Specifies the name of the website for which this
environment is created. To get or to verify the
website name, use the Get-AzureWebsite cmdlet.
.PARAMETER Storage
Specifies a hashtable of values about a Windows
Azure storage account. The New-AzureStorage.ps1 script
returns this hashtable.
.PARAMETER Sql
Specifies a hashtable of values about a Windows
Azure database server and the member and application
databasaes. The New-AzureSql.ps1 script returns this
hashtable.
.INPUTS
System.String
System.Collections.Hashtable
.OUTPUTS
None. This function creates and saves a
website-environment.xml file to disk in the
script directory.
.EXAMPLE
$sqlHash = .\New-AzureSql.ps1 -Password P@ssw0rd
$storageHash = .\New-AzureStorage.ps1 -Name ContosoStorage
New-EnvironmentXml -EnvironmentName MyWebSite -WebsiteName MyWebSite `
-Storage $storageHash -Sql $sqlHash
.LINK
New-AzureWebsiteEnv.ps1
.LINK
Get-AzureWebsite
#>
Function New-EnvironmentXml
{
Param(
[String]$EnvironmentName,
[String]$WebsiteName,
[System.Collections.Hashtable]$Storage,
[System.Collections.Hashtable]$Sql
)
[String]$template = Get-Content $scriptPath\website-environment.template
$xml = $template -f $EnvironmentName, $WebsiteName, `
$Storage.AccountName, $Storage.AccessKey, $Storage.ConnectionString, `
([String]$Sql.Server).Trim(), $Sql.UserName, $Sql.Password, `
$Sql.AppDatabase.Name, $Sql.AppDatabase.ConnectionString, `
$Sql.MemberDatabase.Name, $Sql.MemberDatabase.ConnectionString
$xml | Out-File -Encoding utf8 -FilePath $scriptPath\website-environment.xml
}
<#
.SYNOPSIS
Creates the pubxml file that's used to deploy the website.
.DESCRIPTION
The New-PublishXml function creates and saves
to disk a <website_name>.pubxml file. The file includes
values from the publishsettings file for the website. Windows
Azure requires a pubxml file to deploy a website.
New-PublishXml requires a pubxml.template file in the
script directory. This file is packaged with the
New-AzureWebsiteEnv.ps1 script. If the template file
is missing, the function will fail.
This function is designed as a helper function for
the New-AzureWebsiteEnv.ps1 script.
.PARAMETER WebsiteName
Specifies the name of the website for which this
environment is created. To get or to verify the
website name, use the Get-AzureWebsite cmdlet.
.INPUTS
System.String
.OUTPUTS
None. This function creates and saves a
<WebsiteName>.xml file to disk in the
script directory.
.EXAMPLE
New-PublishXml -WebsiteName MyWebSite
.LINK
New-AzureWebsiteEnv.ps1
.LINK
Get-AzureWebsite
#>
Function New-PublishXml
{
Param(
[Parameter(Mandatory = $true)]
[String]$WebsiteName
)
# Get the current subscription
$s = Get-AzureSubscription -ExtendedDetails -Current
if (!$s) {throw "Cannot get Windows Azure subscription. Failure in Get-AzureSubscription in New-PublishXml in New-AzureWebsiteEnv.ps1"}
$thumbprint = $s.Certificate.Thumbprint
if (!$thumbprint) {throw "Cannot get subscription cert thumbprint. Failure in Get-AzureSubscription in New-PublishXml in New-AzureWebsiteEnv.ps1"}
# Get the certificate of the current subscription from your local cert store
$cert = Get-ChildItem Cert:\CurrentUser\My\$thumbprint
if (!$cert) {throw "Cannot find subscription cert in Cert: drive. Failure in New-PublishXml in New-AzureWebsiteEnv.ps1"}
$website = Get-AzureWebsite -Name $WebsiteName
if (!$website) {throw "Cannot get Windows Azure website: $WebsiteName. Failure in Get-AzureWebsite in New-PublishXml in New-AzureWebsiteEnv.ps1"}
# Compose the REST API URI from which you will get the publish settings info
$uri = "https://management.core.windows.net:8443/{0}/services/WebSpaces/{1}/sites/{2}/publishxml" -f `
$s.SubscriptionId, $website.WebSpace, $Website.Name
# Get the publish settings info from the REST API
$publishSettings = Invoke-RestMethod -Uri $uri -Certificate $cert -Headers @{"x-ms-version" = "2013-06-01"}
if (!$publishSettings) {throw "Cannot get Windows Azure website publishSettings. Failure in Invoke-RestMethod in New-PublishXml in New-AzureWebsiteEnv.ps1"}
# Save the publish settings info into a .publishsettings file
# and read the content as xml
$publishSettings.InnerXml > $scriptPath\$WebsiteName.publishsettings
[Xml]$xml = Get-Content $scriptPath\$WebsiteName.publishsettings
if (!$xml) {throw "Cannot get website publishSettings XML for $WebsiteName website. Failure in Get-Content in New-PublishXml in New-AzureWebsiteEnv.ps1"}
# Get the publish xml template and generate the .pubxml file
[String]$template = Get-Content $scriptPath\pubxml.template
($template -f $website.HostNames[0], $xml.publishData.publishProfile.publishUrl.Get(0), $WebsiteName) | Out-File -Encoding utf8 ("{0}\{1}.pubxml" -f $scriptPath, $WebsiteName)
}
function Get-MissingFiles
{
$Path = Split-Path $MyInvocation.PSCommandPath
$files = dir $Path | foreach {$_.Name}
$required= 'New-AzureSql.ps1',
'New-AzureStorage.ps1',
'New-AzureWebsiteEnv.ps1',
'pubxml.template',
'website-environment.template'
foreach ($r in $required)
{
if ($r -notin $files)
{
[PSCustomObject]@{"Name"=$r; "Error"="Missing"}
Write-Verbose "MISSING FILE: $r"
}
}
}
# End - Helper funtions -----------------------------------------------------------------------------------------------------------------------------
# Begin - Actual script -----------------------------------------------------------------------------------------------------------------------------
# Set the output level to verbose and make the script stop on error
$VerbosePreference = "Continue"
$ErrorActionPreference = "Stop"
# Get the time that script execution starts
$startTime = Get-Date
Write-Verbose "Checking for required files."
$missingFiles = Get-MissingFiles
if ($missingFiles) {$missingFiles; throw "Required files missing from WebSite subdirectory. Download and upzip the package and try again."}
# Running Get-AzureWebsite only to verify that Azure credentials in the PS session have not expired (expire 12 hours)
# If the credentials are expired, cmdlet throws a terminating error that stops the script.
Write-Verbose "Verifying that Windows Azure credentials in the Windows PowerShell session have not expired."
Get-AzureWebsite | Out-Null
Write-Verbose "[Start] creating Windows Azure website environment: $Name"
# Get the directory of the current script
$scriptPath = Split-Path -parent $PSCommandPath
# Define the names of website, storage account, SQL Azure database and SQL Azure database server firewall rule
$Name = $Name.ToLower()
$storageAccountName = $Name + "storage"
$sqlAppDatabaseName = $Name + "_db"
$sqlDatabaseServerFirewallRuleName = $Name + "rule"
Write-Verbose "Creating a Windows Azure website: $Name"
# Create a new website
# The New-AzureWebsite cmdlet is exported by the Azure module.
$website = New-AzureWebsite -Name $Name -Location $Location -Verbose
if (!$website) {throw "Error: Website was not created. Terminating the script unsuccessfully. Fix the errors that New-AzureWebsite returned and try again."}
Write-Verbose "Creating a Windows Azure storage account: $storageAccountName"
# Create a new storage account
$storage = & "$scriptPath\New-AzureStorage.ps1" -Name $storageAccountName -Location $Location
if (!$storage) {throw "Error: Storage account was not created. Terminating the script unsuccessfully. Fix the errors that New-AzureStorage.ps1 script returned and try again."}
Write-Verbose "Creating a Windows Azure database server and databases"
# Create a SQL Azure database server, app and member databases
$sql = & "$scriptPath\New-AzureSql.ps1" -ApplicationDatabaseName $sqlAppDatabaseName -UserName $SqlDatabaseUserName -Password $SqlDatabasePassword -FirewallRuleName $sqlDatabaseServerFirewallRuleName -StartIPAddress $StartIPAddress -EndIPAddress $EndIPAddress -Location $Location
if (!$sql) {throw "Error: The database server or databases were not created. Terminating the script unsuccessfully. Failures occurred in New-AzureSql.ps1."}
Write-Verbose "Attempting to save off storage.AccessKey to new variable..."
$storageAccountKey = $storage.AccessKey;
Write-Verbose "[Start] Adding settings to website: $Name"
$appSettings = @{ `
"StorageAccountName" = $storageAccountName; `
"StorageAccountAccessKey" = $storage.AccessKey; `
"MicrosoftAuthClientId" = ""; `
"MicrosoftAuthClientSecret" = ""; `
"TwitterAuthConsumerKey" = ""; `
"TwitterAuthConsumerSecret" = ""; `
"FacebookAuthAppId" = ""; `
"FacebookAuthAppSecret" = ""; `
"GoogleAuthClientId" = ""; `
"GoogleAuthClientSecret" = ""; `
"StorageConnectionString" = "DefaultEndpointsProtocol=https;AccountName=$storageAccountName;AccountKey=$storageAccountKey"; `
"AzureWebJobsDashboard" = "DefaultEndpointsProtocol=https;AccountName=$storageAccountName;AccountKey=$storageAccountKey"; `
"AzureWebJobsStorage" = "DefaultEndpointsProtocol=https;AccountName=$storageAccountName;AccountKey=$storageAccountKey"; `
}
# Configure connection strings for appdb and ASP.NET member db
$connectionStrings = ( `
@{Name = "DefaultConnection"; Type = "SQLAzure"; ConnectionString = $sql.AppDatabase.ConnectionString}
)
Write-Verbose "Adding connection strings and storage account name/key to the new $Name website."
# Add the connection string and storage account name/key to the website
$error.clear()
Set-AzureWebsite -Name $Name -AppSettings $appSettings -ConnectionStrings $connectionStrings
if ($error) {throw "Error: Call to Set-AzureWebsite with database connection strings failed."}
Write-Verbose "[Finish] Adding settings to website: $Name"
Write-Verbose "[Finish] creating Windows Azure environment: $Name"
# Write the environment info to an xml file so that the deploy script can consume
Write-Verbose "[Begin] writing environment info to website-environment.xml"
New-EnvironmentXml -EnvironmentName $Name -WebsiteName $Name -Storage $storage -Sql $sql
if (!(Test-path $scriptPath\website-environment.xml))
{
throw "The script did not generate a website-environment.xml file that is required to deploy the website. Try to rerun the New-EnvironmentXml function in the New-AzureWebisteEnv.ps1 script."
}
else
{
Write-Verbose "$scriptPath\website-environment.xml"
Write-Verbose "[Finish] writing environment info to website-environment.xml"
}
# Generate the .pubxml file which will be used by webdeploy later
Write-Verbose "[Begin] generating $Name.pubxml file"
New-PublishXml -Website $Name
if (!(Test-path $scriptPath\$Name.pubxml))
{
throw "The script did not generate a $Name.pubxml file that is required for deployment. Try to rerun the New-PublishXml function in the New-AzureWebisteEnv.ps1 script."
}
else
{
Write-Verbose "$scriptPath\$Name.pubxml"
Write-Verbose "[Finish] generating $Name.pubxml file"
}
Write-Verbose "Script is complete."
# Mark the finish time of the script execution
$finishTime = Get-Date
# Output the time consumed in seconds
$TotalTime = ($finishTime - $startTime).TotalSeconds
Write-Output "Total time used (seconds): $TotalTime"
# End - Actual script ------------------------------------------------------------------------------------------------------------------------------- -