这是你的情况:你有一堆网站上传统的托管模式。共享的租户在单一的逻辑机器上,专门的基础设施或更糟的是,没有任何想法,因为你一直付每月5美元等等工作。大部分的时间。
但你看到光和你想搬东西Azure集体。少量的网站不是戏剧,有一些设置工作为每一个创造Azure资源,只要你遵循一组预定义的步骤就完美,你很好。但像大多数事情一样,需要手动步骤,它很容易出错的一切刚刚好每次和也很费力。一旦把网站变成了几十个,它开始觉得有点艰苦的工作。不仅如此,但你会希望在Azure新资产在未来,瞬间将附近的一个可重复的方法好。
我最近这一挑战——“我们想一堆网站迁移到Azure和他们会融入基本相同的模式”——因此而不是人们在Azure门户点击链接,我给了他们一个PowerShell脚本并释放它们。我给你的所有步骤,解释它是如何运作的和给你整个PowerShell脚本,这样你不必从头开始的所有螺母和螺栓。享受吧!
准备
首先,你需要一个Azure订阅。好吧,有点明显但你不能跳进PowerShell命令并开始运行。我也已经有了一个网站,这意味着已经有一个合适的托管计划加上我有一个SQL Azure数据库(记住这是PaaS提供,而不是一个完全成熟的独立的SQL Server可以RDP到),这意味着已经有一个数据库服务器和适当的防火墙规则。这是假设我在这里,如果我可以提个建议,只是一次性的东西在浏览器中设置值得做而不是试图为自己的命令。事实上即使你将脚本的整个过程,做一个手工一分之一和找出如何你想让你的最终状态。
开始使用Azure PowerShell
首先假设:假设你有Azure PowerShell启动并运行如果情况并非如此,花上几分钟如何安装和配置Azure PowerShell吗页面,把一切都打好了。确保你可以加载一个Azure PowerShell会话然后继续读下去。
这里有一个快速pro提示:检查你的订阅!不止一次,我想知道为什么PowerShell变化我没有出现在Azure门户网站,它将总是我在一个不正确的订阅。保存自己的痛苦如果你可以访问多个订阅和总是运行这个开始前:
Get-AzureSubscription
你会看到你所有的订阅列表,每一个都有一个“IsCurrent”属性。如果你看到一些你不曾预料到的,电影在正确的正事之前:
Select-AzureSubscription“特洛伊的订阅”
哦,如果你要继续回到这个订阅和它不是已经默认了,这里有你需要的东西:
Select-AzureSubscription默认-SubscriptionName“特洛伊的订阅”
上有一堆引用网络命令不工作与当前一代的Azure的api,这样会节省您的一些痛苦,至少直到它再次改变,这就变成了另一个不正确的参考!但是说真的,要意识到API的改变在破坏方面,你很可能会发现命令不再是正确的。
完成了,让我们开始创建的东西!
创建和删除网站
这一点可以易如反掌,只是一个命令:
New-AzureWebSite TroyPSTest
将秒,之后你会有以下:
实例:{}NumberOfWorkers: 1 DefaultDocuments:{违约。htm,违约。html,违约。asp,你……}NetFrameworkVersion: v4.0 PhpVersion: 5.4 RequestTracingEnabled:假HttpLoggingEnabled:假DetailedErrorLoggingEnabled:假PublishingUsername:美元TroyPSTest PublishingPassword: mZvMGi2GfDc2iCepcPm6vsEd9hLxvtk3wl5NNtHxWaMqHDjAY8Apka4fXM3W AppSettings: {WEBSITE_NODE_DEFAULT_VERSION}元数据:{}ConnectionStrings: {} HandlerMappings:{}名称:TroyPSTest状态:运行主机名:{troypstest.azurewebsites.net}网站:AustraliaEastwebspace SelfLink: https://waws -刺激sy3 - 001. - api.azurewebsites.windows.net: 454 / subsc器具/ 62 e2a1e5 - 4 - eda cie - 805 - e - 44 - a6c8f8afbd Eastwebspace /网站/澳大利亚/网站/ TroyPSTest RepositorySiteName: TroyPSTest Sku:免费UsageState:正常启用:真正的AdminEnabled:真正的EnabledHostNames: {troypstest.azurewebsites.net, troypstest.scm.azurewebsites.net} SiteProperties: Microsoft.WindowsAzure.Commands.Utilities.Websites.Services。WebEn tities。SiteProperties AvailabilityState:正常HostNameSslStates: {troypstest.azurewebsites.net, troypstest.scm.azurewebsites.net} AzureDriveTraceEnabled: AzureDriveTraceLevel:错误AzureTableTraceEnabled: AzureTableTraceLevel:错误AzureBlobTraceEnabled: AzureBlobTraceLevel:错误ManagedPipelineMode:集成WebSocketsEnabled:假RemoteDebuggingEnabled:假RemoteDebuggingVersion: VS2012 RoutingRules: {} Use32BitWorkerProcess:真正的AutoSwapSlotName: SlotStickyAppSettingNames: {} SlotStickyConnectionStringNames: {}
有一个浏览条款,主要是熟悉你如果你花了一些时间在Azure网站,但你可能不习惯看到它一起坐在那里。然而,这应该非常熟悉老练的Azure网站用户:

这只是你平常门户尽管新网站现在出现在列表中。记住,PowerShell只是一个接口为最终相同的底层平台你使用的浏览器,的方式快!不过,还有一个问题:这个网站创建了“澳大利亚东部”的位置和设置免费赠品。我真的很想把它在美国西部,让它标准坐在我现有的逻辑机器,不收我任何更多的现金。没有问题,我们就核网站:
Remove-AzureWebsite - name TroyPSTest
你会得到一个确认提示(您可以覆盖“force”参数),对,就是这样,网站不见了!花一些时间来喝,我们创建和删除网站通过命令行一样轻松地在一些遥远的远程位置我们创建一个本地文件夹。当你可以管理资源在这种低摩擦的方式,你可以开始真正改变你工作的方式在一个非常积极的方式。
创建网站在正确的位置
继续,我们需要适应原始命令获取该网站在正确的位置。有一个“位置”参数,可以应用于网站创建这原始命令现在更改:
New-AzureWebSite TroyPSTest位置“西方我们”
清楚你想要的位置可能不同所以小心如果你复制粘贴!回到门户在浏览器中,现在我们发现它在正确的地方:

记住——目前仍然没有迁移设备之间自动洗牌资产数据中心所以确保你有这个权利之前否则你几乎要从头重新开始。你会看到价格层仍然是“免费”;我们不久就会回来,这不是我们可以配置在创建的网站。
设置网站参数
当你站起来一个新的Azure网站,默认情况下你会得到:

现在因为我很安全意识的人(所以你应该),我真的不想上运行PHP站点。这并不是因为对PHP本身有什么不好,只是我不需要它。让我们把它关掉:
$属性= @ {phpVersion = " "} Set-AzureRmResource - name resourcetype“TroyPSTest微软。Web /网站/ config / Web Default-Web-WestUS“-ResourceGroupName属性属性-ApiVersion 2015-08-01 force美元
死容易,但只有这么多,我们可以使用Set-AzureWebsite配置。对于一切,我们将需要跳过到Azure资源管理器让我们这样做,解决定价层。
配置价格层
定价层是一个小技巧,不是我们可以设置时创建的网站也使用Set-AzureWebsite cmdlet,而是要求我们修改网站一旦创建。很好,我们需要做一点,后来无论如何,它会要求我们跳过资源管理器模式:
Switch-AzureMode AzureResourceManager
这给了你一套全新的cmdlets可以使用管理环境你没有得到的Azure管理Cmdlets这是我们只是使用。你会看到我跳出这个模式和最初的模式称为服务管理模式,我们需要访问不同的cmdlets集。
现在我们要做的就是开始工作资源组。认为这些是一个逻辑Azure订阅内资产的集合,例如我所有的网站都在一个叫做“Default-Web-WestUS”。你可以找到在Azure门户通过资源组链接:

我们也需要我们使用Azure API的版本去抓住,再一次,是有意识的,它可能会改变随着时间的推移破坏方式。现在我们可以检索网站,并将其分配给一个变量我叫“$ r”(小心如果你复制粘贴,你有正确的API版本):
$ r = Get-AzureResource - name TroyPSTest -ResourceGroupName Default-Web-WestUS resourcetype微软。Web /站点-ApiVersion 2014-04-01
网站现在分配给变量,我们可以开始执行各种操作,包括列出所有已知属性,只需键入$ r和运行该命令。验证有时很好,因为我们要做在接下来的几个步骤将更改站点,我们不想无意中使这些错误的网站上。列出的价值$ r会给你一个JSON堆;另一件事我们可以做的是打印的一个子集等信息直接实体的属性:
r.Properties美元
这将给我们一个键值对每个属性:
键值- - - - - - - - - - - -名字TroyPSTest状态运行主机名{troypstest.azurewebsites.net}网站westuswebspace selfLink https://waws -刺激湾- 003. - api.azurewebsites.windows.net:……repositorySiteName TroyPSTest所有者usageState 0启用真adminEnabled真enabledHostNames {troypstest.azurewebsites.net troypstest.scm.azurewebsi……siteProperties{(元数据),[属性,System.Collections.Generic.L……availabilityState 0 sslCertificates csr {} cer siteMode hostNameSslStates {System.Collections.Generic.Dictionary 2 [System.String,年代……computeMode serverFarm Default2 webHostingPlan Default2 lastModifiedTimeUtc 22/12/2014 00:57:04 storageRecoveryDefaultState运行contentAvailabilityState runtimeAvailabilityState 0 siteConfig deploymentId TroyPSTest trafficManagerHostNames sku免费premiumAppDeployed scmSiteAlsoStopped假targetSwapSlot hostingEnvironment cloningInfo microService网站
现在我们要做的是改变几个属性,让网站进入正确的定价层。默认情况下,创建网站时进入了一个新的服务器农场新web托管计划,我们已经知道,定价层(也称为SKU)被设置为“免费”。现在我们要做的就是设置这些属性结合我的其他网站通过分配一个数组的适当的名称值对一个新的变量我们叫$ p:
$ p = @ {“sku”=“标准”;“serverFarm”=“DefaultServerFarm”;“webHostingPlan”=“DefaultServerFarm”}
现在的最后一步是将这些属性回到新网站像这样:
$ r2 = Set-AzureResource - name TroyPSTest -ResourceGroupName Default-Web-WestUS resourcetype微软。Web /站点-ApiVersion 2014-04-01美元-PropertyObject p
我输出结果美元r2所以很容易检查新设置后他们被应用。只是一个检查,让我们来看看现在情况看门户:

好吧,看起来更好,可以肯定的是他们实际上使用相同的托管计划并没有花费我额外的美元,让我们点击简介:

这是伟大的,他们都在那里同行资源,默认的服务器农场,这样做。
添加一个分段的部署位置
非常整洁的事情之一Azure网站服务的能力部署位置进行部署。这意味着你可以把你的网站一个孤立的实例,你可以测试它,并确保事情玩好之前对它进行现场站点在您的生产领域。不仅如此,但你甚至可以开始路由流量的比例不同的槽与一个新版本的网站在所谓的“生产测试”。这将使传统的头旋转——“生产测试——你不能这么做!”——但它很有意义的生产准备网站受到一小部分听众首先要确保一切都好。
我将返回到Azure管理cmdlets现在我想创建一个新的服务。
Switch-AzureMode AzureServiceManagement
添加一个部署槽是小菜一碟:
New-AzureWebsite TroyPSTest位置“西方我们“槽”阶段”
注意,这是相同的命令之前,我们只是传递给它一个“槽”参数。真正注意到这一点——一个“网站”可能有很多“槽”,稍后您将看到如何命令不显式地引用槽严重失败,而一旦你不仅仅是默认的。跳过门户,现在您应该看到它出现在原来的网站作为一个新的部署位置:

重要的是要注意,这个网站继承了我们之前设置的托管计划和定价层。这也是继承了PHP设置为新网站将自动禁用。
创建SQL Azure数据库
现在在开始下一个过程的一部分,之前我已经有了一个SQL Azure数据库,我想把所有其他的在相同的实例。这意味着我已经有一个服务器的名字——“snyb5o1pxk”——加上我已经凭据访问“上帝权利”和适当的防火墙规则进行远程连接我的IP地址。作为一个为服务器,这是值得这样做就直接在门户中。哦,以防你开始思考创建单独的服务器为每个项目时,一定要有意识的Azure订阅服务限制,配额和约束。
的命令提供服务器上的数据库,这是一个非常类似的交易如何创建网站,它看起来就像这样:
$ db = New-AzureSqlDatabase servername snyb5o1pxk“数据库名“TroyPSTestDB”版“基本”-MaxSizeGB 2
我们不一定需要$ db变量分配结果,但它很容易在任何时间打印到屏幕上后,看看我们有什么:
名称:TroyPSTestDB CollationName: SQL_Latin1_General_CP1_CI_AS版:基本MaxSizeGB: 2 MaxSizeBytes: 2147483648 ServiceObjectiveName:基本ServiceObjectiveAssignmentStateDescription:完整的创建日期:22/12/2014 11:51:28 RecoveryPeriodStartDate: 22/12/2014 12:21:27
就是这么简单的事情,我们现在有一个DB !
标签的资源
发生了一件事当你开始得到大量的资源门户是事情变得混乱。标签在Azure类似标签你熟悉说,在这个博客:零功能价值,但它使逻辑相关的东西组合在一起。
首先,回到资源管理器模式:
Switch-AzureMode AzureResourceManager
您可以应用一个标签之前,您需要创建一个。我决定标签的项目名称,你也可以标记由环境(阶段,测试)或任何其他分类你决定申请。这是我的样子:
New-AzureTag - name项目价值TroyPSTest
我们现在可以在许多地方使用这个标签,即确定网站和数据库资源属于一个逻辑组。现在让我们把它应用到该网站:
$ r2 = Set-AzureResource - name TroyPSTest -ResourceGroupName Default-Web-WestUS resourcetype微软。Web /站点-ApiVersion 2014-04-01 -PropertyObject $ p标记@ {Name =“项目”;值= " TroyPSTest "}
请注意,我们前面定义的属性变量也过去了。而doco州这是可选的,我发现PowerShell不是真的快乐当它没有得到这个(我说这是一个小变化无常的,对吧?)。不要紧,已经定义了所以我就扔回参数集合。当然,明智的做法是使用单个Set-AzureResource命令并通过属性和标签,上面的方法是引入不同的概念。
让我们也标记SQL数据库:
Set-AzureResource - name TroyPSTestDb -ResourceGroupName Default-SQL-WestUS -ParentResource服务器/ snyb5o1pxk resourcetype微软。Sql /服务器/数据库-ApiVersion 2014-04-01标签@ {Name =“项目”;值= " TroyPSTest "}
在门户网站和DB现在坐在彼此“TroyPSTest”标签:

对的,现在我感觉非常有组织!
在网站上设置主机名
这里有点鸡和蛋的你:你会想要一个主机名在网站上这意味着你将会想要运行这样的:
Set-AzureWebsite - name TroyPSTest主机名@ (“troypstest.troyhunt.com”)
然而,这将给你:
Set-AzureWebsite: BadRequest:一个CNAME记录从troypstest.troyhunt.com指向troypstest.azurewebsites.net文件不存在。选择awverify.troypstest.troyhunt.com, awverify.troypstest.azurewebsites.net也没有找到记录。
如果你曾经通过门户主机名添加到一个网站之前,你就会知道这是不可能的,直到你的域上创建一个CNAME记录。然而,您需要知道在Azure网站的名称你可以这么做,而这是您自己提供的名称,它还需要是唯一的,而不是使用任何现有的Azure网站所拥有的任何人。你可以去和配置您的DNS记录之前运行该脚本假设你选择网站名称(因此进入CNAME)将被允许,但如果是“foo”然后你要回去以后再编辑DNS。
创建一个SQL登录和用户
之一,我们需要做的最后一件事是确保网站可以连接到数据库,这意味着创建一个新的SQL登录。是的,你可能该网站使用当你第一次提供的凭证创建服务器,但没有,不这样做。你不希望匿名的人们在你的网站,然后连接到数据库使用特权帐户,可以做任何事情,它想要的。你想要的是一个独特的解释程序,你可以走了最小特权原则上。
创建登录时通过PowerShell,没有本地命令这样做所以我们要用SMO对远程服务器运行的SQL命令。要做到这一点,我们需要进口SQLPS模块第一:
Import-Module SQLPS -DisableNameChecking
现在我们可以继续,连接到现有SQL server并选择主数据库到一个新的$ db变量:
康涅狄格州美元。ConnectionString = " =主服务器= tcp: snyb5o1pxk.database.windows.net;数据库;用户ID = troyhunt;密码= P@ssw0rd;”$srv = New-Object "Microsoft.SqlServer.Management.Smo.Server" $conn $db = $srv.Databases["master"]
做,让我们创建一个SQL登录我们称之为“TroyPSTestDbUser”:
$登录=新对象-TypeName Microsoft.SqlServer.Management.Smo。登录-ArgumentList srv美元,“TroyPSTestDbLogin”登录。LoginType = " SqlLogin "美元登录。PasswordPolicyEnforced =假美元登录。PasswordExpirationEnabled = false login.Create美元(“S0m3thingR3@llyR@nd0mTh@tI ntThi美元”)
接下来我们将创建一个登录的用户在DB:
db = srv美元。数据库(“TroyPSTestDb”) $ dbus =新对象-TypeName Microsoft.SqlServer.Management.Smo。用户-ArgumentList $ db,“TroyPSTestDbUser”dbus美元。登录= " TroyPSTestDbLogin " $ dbUser.Create ()
就是这样——工作!当然你仍然需要把这个用户的角色在你的数据库后将其部署到Azure和给它适当的权利,但是现在都坐在那里等着你。做注意密码和设置是如何定义的,这并不是一个特别管理(或获得)如果你要策划这个集体,但我会回到这稍后兆脚本,有一件事我想做第一个…
将连接字符串添加到网站
好,最后在配置:我想确保网站是预先配置的数据库的连接字符串。我们已经知道所有的连接细节,现在只是建立字符串并调用适当的PowerShell命令。这是所有的部分:
美元connStr = " snyb5o1pxk.database.windows.net服务器= tcp: 1433;数据库= TroyPSTestDb;用户ID = TroyPSTestDbLogin@snyb5o1pxk;密码= S0m3thingR3@llyR@nd0mTh@tI ntThi;美元Trusted_Connection = False;加密= True;连接超时= 30;”$connStrInfo = New-Object Microsoft.WindowsAzure.Commands.Utilities.Websites.Services.WebEntities.ConnStringInfo $connStrInfo.Name=TroyPSTestDb $connStrInfo.ConnectionString=$connStr $connStrInfo.Type="SQLAzure" $connStrSettings = (Get-AzureWebsite TroyPSTest -Slot "production").ConnectionStrings $connStrSettings.Add($connStrInfo) Set-AzureWebsite -Name TroyPSTest -Slot "production" -ConnectionStrings $connStrSettings
现在这里有一件事我想特别提请注意的槽Get-AzureWebsite和Set-AzureWebsite命令的参数。错过这个,你就会花了长时间打你头撞墙纳闷为什么你得到关于null对象的异常当网站的名字显然是正确的。你看,当网站有多个插槽等什么上面的“舞台”我们说,没有明确指定位置会让你高和干燥,它将返回一组描述插槽。如果你只有一个默认位置的命令就会隐式地适用于这一个网站,你会得到一个实体,所以当你看到那些“服务条款”,看起来这么简单但不为你工作,这很可能是为什么!我有没有提到可以令人沮丧,完全相同的命令相同的参数完全可以返回不同类型基于资源的状态?
移动的门户,我们现在有这个:

连接字符串名称需要与一个在您的web。配置部署后它可能意味着改变网站的自动应用到网站。
专业技巧
会出错,你会得到错误的东西。错误可能不会告诉你为什么,例如,当向数据库添加一个标签:
Set-AzureResource:处理这个请求时发生一个错误。行:1字符:1 + Set-AzureResource - name dbName -ResourceGroupName dbResourceGroup美元-ParentResou……+ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ + CategoryInfo: CloseError: (:) [Set-AzureResource], CloudException + FullyQualifiedErrorId: Microsoft.Azure.Commands.Resources.SetAzureResourceCommand
哦,“发生了一个错误”!原因不明的东西出错时,曲柄冗长:
美元DebugPreference = "继续"
如果你不想额外的噪声一旦整理东西,抚慰它回落:
美元DebugPreference = " SilentlyContinue "
另一个要考虑的是约定。如果你要申请这个过程一堆网站,那么你要考虑你的命名。我用以下约定:
- = $ projectName网站名称
- 数据库名称= $ projectName +“数据库”
- 数据库登录= $数据库名+“登录”
- 数据库用户名= $数据库名+“用户”
- = $ projectName标签的名字
最后一件事,你不会这样的,不要低估小字的意义:

我的大支持者Azure但老实说,说我必须让孩子们离开房间之前表达我的感受关于PowerShell命令的一致性实际工作。我知道我之前提到过,这是一个真正的痛苦就记住的东西不工作时,它并不总是你的错,可能是某人的其他好的建议,为他们工作,但现在可能不相关。
脚本出来
首先,要小心——龙吧!我们要自动脚本整件事即单击创建一堆东西将触及你的底线。Azure服务是便宜,你创造足够的足够快,你可能会讨厌的惊喜。
——这个脚本快速警告无非是上面的命令在一个逻辑顺序和使用一些环境变量来保存一堆硬编码的刺。这不是一个优雅PowerShell脚本如果你想要一个很好的参考点,看看这个例子创建一堆Azure资源。
这是整件事情:
看起来很简单的吗?,摧毁这一切是一样简单这里核一切您刚刚创建的脚本,这样您就可以玩然后删除所有之前触及你的底线:
就是这样,容易对吧? !
其他注意事项和总结
我在这里采取了一些快捷方式,你可能想给更多的认为如果你要遵循这一过程。缺乏错误弹性在上面的脚本就是一个例子。例如,如果资源名称你想创建已经存在或连接下降,中途会失败。没有一个专门的数据库的登台环境是另一个例子,当然你现在得到了脚本创建一个额外的一个如果你请。同样的再处理缺乏舞台环境的连接字符串。
最主要的我想在这里虽然是所有这些脚本,可自动化的,也许最重要的是,可重复的。漫长的日子一去不复返了获得基础设施意味着漫长的形式,长期承诺和漫长的等待时间,这些天只是一个PowerShell脚本。这是相当了不起的。