将WSP部署为自动生成的一部分(Chris O’Brien)

Categories: Other
Tags: No Tags
Comments: No Comments
Published on: 2012 年 03 月 26 日

[原文发表地址]  Deploying WSPs as part of an automated build (Chris O’Brien)

[原文发表时间]  2011-11-17 8:15 AM

在我们的 SharePoint 持续集成系列的第五篇文章中,我们将看看如何实现自动的 WSP 部署,并作为团队基础服务器 (TFS) 生成的一部分。我们在较早的文章中已处理了大多数的前提条件,但由于我们仍然有一个优秀前提需要覆盖到,所以这篇文章被分成两部分:

  • 配置PowerShell远程处理
  • 将WSP部署为生成过程的一部分

此外,我们还会介绍SharePoint/TFS 持续集成初学者工具包— — 这是一个 Codeplex 项目,其中包含 TFS 的工作流和本文中引用的 PowerShell 部署脚本。

配置PowerShell远程处理

一旦你使用 TFS 生成自动化程序集的生成和WSP 包,很可能你想要部署 WSP 到 SharePoint 环境中来对其进行测试。除非TFS 生成服务器上安装了SharePoint 2010(有几个理由很少推荐这个配置,并非所需资源的配置),这意味着部署WSP到远程的物理或虚拟服务器上。由于 PowerShell 是WSP 部署脚本的最有效方式,所以必须在TFS 生成服务器和 SharePoint 服务器之间配置PowerShell 远程处理,以确保可以进行远程交流。好消息是这相当简单。这里列出的步骤与Jie Lie的 SharePoint 2010与Windows PowerShell远程处理的分布配置博客文章中所陈述的是相同的 — — 这里的步骤只是有了一些围绕自动生成的额外的上下文。在配置方面,我们需要实现以下目标:

  • 启用 PowerShell 远程处理
  • 配置 CredSSP身份验证,以允许从生成服务器到 SharePoint 服务器的凭据委派。这允许与 SharePoint 一起运行的cmdlet起源于生成服务器
  • 将PowerShell 写入的内存限制提高到一个适合长时间运行 SharePoint 命令的值

所需的权限

若要针对 SharePoint 运行 PowerShell cmdlet,所使用的帐号必须为WSS_Admin_WPG Windows 安全组的成员,也需是正在运行的特定数据库 (如 SharePoint 配置数据库或包含团队站点的内容数据库)中SharePoint_Shell_Access 角色的成员。这种组合称为 Shell 访问,并授权运行Add-SPShellAdmin cmdlet。

配置过程

  • 在 SharePoint 服务器上:
    • 通过选择“以管理员身份运行”来使用高级管理员权限打开SharePoint 2010 Management Shell
    • 通过运行以下 cmdlet 来启用 PowerShell 远程处理:Enable- PSRemoting
    • 使用 CredSSP以让服务器能够接受凭据:Enable-WSManCredSSP –Role Server
    • 将PowerShell 内存级别提高到 1 GB:Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 1024
  • 在TFS 生成代理服务器上:
    • 通过选择“以管理员身份运行”来使用高级管理员权限打开Windows PowerShell提示。
    • 如果以前没有在此服务器上执行此操作,将PowerShell执行策略设置为允许运行脚本— — 至少策略必须是 RemoteSigned:
      Set-ExecutionPolicy RemoteSigned

  • 使用 CredSSP以让服务器能够传递凭据— — 用你的SharePoint 服务器的名称替换样品名称:Enable-WSManCredSSP -Role client -DelegateComputer "MySharePointServer"
    -注意DelegateComputer参数的其他允许值包含"*. mydomain.com"和"*"。然而,最安全的做法是将凭据委派的范围限制为尽可能的小。
  • 测试 PowerShell 远程处理和 CredSSP 身份验证:
    • 在TFS生成的代理服务器上,通过启动远程会话到SharePoint 服务器上来测试远程处理:Enter-PSSession -ComputerName "MySharePointServer"成功的测试是能将命令提示符所在的位置更改为 [MySharePointServer]: PS C:\Users\<username>
    • 键入exit以关闭远程会话
    • 在 TFS 生成的代理服务器上,使用以下cmdlet来测试CredSSP 验证:Enter-PSSession -ComputerName "MySharePointServer" -Authentication CredSSP –Credential Get-Credential——这将强制弹出一个身份验证提示来输入用户名和密码 — — 指定具有 SharePoint 服务器权限的域帐户。与以前一样,成功的测试要更改命令提示符所在的位置。

现在远程处理的配置应该允许 WSP 包的远程部署。

WSP 包部署为生成过程的一部分

回顾一下,到目前为止,我们在这一系列中已完成以下操作:

  • 配置生成定义来编译我们的代码以及生成 WSP
  • 添加测试修改到生成工作流中,类似于部署 WSP所需的实际修改
  • 配置PowerShell 远程处理以支持 WSP 部署步骤

现在,我们准备实施自动部署我们的 WSP,并作为生成过程的一部分。这篇文章没有提供分步指南 ;在这里我们将讨论关键的机制,但相反建议您下载执行此要点的完整文件。这些是可供下载,并是 Codeplex 项目的一部分的东西:

SharePoint/TFS 持续集成初学者工具包

项目中有安装文档,但这篇文章提供了额外的详细信息,对于那些正在考虑实行此的人,推荐阅读一下。

介绍

当处理自动部署 WSP 作为生成的一部分的挑战时,一种方法是实施一个过程,它定期将 ‘轮询’drop文件夹来挑选软件包。不过,这是次优的,因为生成过程需要更长时间,可能会有时序问题。更为可取的方法是实施一个纯粹由事件驱动的过程, 在WSP 部署开始的位置尽快构建软件包。这就需要修改生成过程工作流,但造就了更为可靠的解决方案。本文中所概述的过程使用了这种方法。

两个高级别重点领域是:

  • 建立工作流-修改一个附带了 TFS 的模板来包括一项触发 WSP 部署过程的活动
  • PowerShell 脚本— — 实施脚本并执行部署步骤。这可以是部署,撤销和部署,或更新软件包,但也要考虑到可能需要其他资源调配的步骤 (例如,激活功能)。这将取决于应用程序

下面的图表概述了这些项目之间的关系,假设在一个多个服务器CI的环境中:image

实际上,构建工作流会调用本地 PowerShell 脚本,它轮流使用 PowerShell 远程处理来调用位于 SharePoint 服务器上的 PowerShell 脚本。正是这个脚本部署了 WSP 和执行其他任何资源调配的步骤。然后返回结果 到生成工作流中。

必须解决以下难题:

  • 特定生成的输出文件夹-对于每个生成,TFS 生成在生成定义指定的drop文件夹中创建一个新的子文件夹。此子文件夹路径称为"拖动位置"。我们必须确保WSP 部署过程使用充分的拖动位置来找到软件包,否则正确的文件不会被部署。
  • 日志记录— —任何来自外部进程(例如PowerShell)的控制台输出必须由生成工作流记录日志。这确保了生成报告中包括错误消息,便于进行故障排除。
  • 收集成功/失败 — —返回值必须从部署脚本传递到主要脚本上,并从那里返回到生成工作流。这是必需的,因为根据结果在工作流中(例如如果成功部署了生成,就运行用户界面测试,但如果没有成功,就跳过) 分支是很常见的事情。

实施持续集成的复杂性在于在工作流/PowerShell中建立机制以应付这些挑战。SharePoint/TFS 持续集成初学者工具包为一个框架提供了这种机制,下一部分将讨论此实现。

建立工作流 — — 挑战和解决方案

当触发一个生成时,会执行与正在运行的生成定义相关联的生成工作流。尽管附带了TFS, 生成工作流模板在 SharePoint 中没有任何WSP 部署的本地知识,只是简单的扩展来集成它— —通常 DefaultTemplate.xaml是最好的起点。正如在之前的文章为SharePoint 项目创建您的第一个 TFS 生成过程中所讨论到的, InvokeProcess活动可以拖动到工作流中来调用外部进程,比如 PowerShell 。这项活动是.NET4工作流工具箱中最有用的活动之一,而且是我们WSP 部署目标的关键。

一旦 InvokeProcess 活动被拖到了工作流,你就可以配置它了,在这里可以解决前面讨论过的几个CI 挑战。下表总结了每个的方法:

生成工作流的挑战

解决方案

生成特定的输出文件夹

来自BuildDetail.DropLocation属性的唯一

drop 文件夹在生成工

作流中是可用的。由于 PowerShell 脚本可以

接受参数,我们应将此字符串作为命

令行参数传递给脚本。

日志记录

InvokeProcess 支持标准的日志记录和来自被

调用过程的错误输出

— — 可以为这些条件添加子

工作流活动。常用的方法是分别为标准日志

记录和错误输出添加WriteBuildInformation

WriteBuildError活动。

收集成功/失败

InvokeProcess 的结果属性将会设为被调用过

程的退出代码。必须小心以确保调用进程的

退出代码公约被理解。通常情况下,0 表示

没有错误,其他任何非零值表示错误状态。

虽然这儿获取了大多数的方式,但还需要做更多的工作来在生成服务器上的主脚本和 SharePoint 服务器上的部署脚本之间传递值。这在下一节中会详细说明,但在我们离开生成工作流之前,让我们看看在InvokeProcess 上配置了上述哪些属性。

将日志记录活动添加到 InvokeProcess 活动中:

clip_image002clip_image003

未配置的                                                              配置过的

在 InvokeProcess 上配置实际属性 (注意我们调用 PowerShell.exe (FileName),并传递给它一些参数,例如要运行的脚本,然后收集退出代码到一个名为 ‘DeploymentProcessExitCode’ 的工作流变量中):

image

当将参数传递给 PowerShell 时, 一个关键的细节是为当前运行的生成传递唯一文件夹位置,这可以通过读 取BuildDetail.DropLocation 属性获得。所以,如果我们单击参数属性旁边的省略号,我们可以看到全部值,它显示了:

image

一旦配置了生成工作流,就可以将其导入。下一步是处理生成过程的 PowerShell 部分。

PowerShell 部署脚本

在这一节中我们将重点关注跨 PowerShell 脚本所需的通信机制: 即传递drop位置文件夹和返回一个值来指示是否部署步骤成功了。在这里PowerShell 的部署步骤的深层覆盖面已超出了范围 — — 在现实世界中有着极其广泛的步骤,它们可能是必需的,这取决于许多因素:

  • 正在部署的应用程序
  • 部署步骤是否展示了应用程序的完整资源调配或针对当前产品状态展示了一组新创建的项目的资源调配,(例如部署升级到最新版本)

因此。每个项目 (事实上,项目内的每个版本) 需要写入适当的 PowerShell以用于其资源调配。不过,在SharePoint/TFS 持续集成初学者工具包中的示例脚本提供了以下信息:

  • 用于在每个WSP生成上(假设已经部署了它们,而且该站点正在运行)运行 Update-SPSolution的方法
  • 用于删除和重新创建测试站点集合的方法 (那样任何测试都运行最新版本的站点和列表模板)
  • 许多实用程序的方法来支持可靠的WSP 部署 (例如应用程序回收站/热身,等待计时器作业完成,如果发现被停止运行,重新启动服务等。)

下一节讨论了参数是如何从生成工作流中流动到主 PowerShell 脚本又再次回到部署脚本中的。

PowerShell 部署脚本 — — 挑战和解决方案

我们刚才看到,生成工作流中的 InvokeProcess 活动将drop位置作为命令行参数传递到了主 PS 脚本中。但是,如何通过脚本接收,以及更重要的是,我们如何使用此值来调用远程服务器上的部署脚本?虽然这些问题可由PowerShell专家轻松地回答出,但对于其他人,以与我们处理生成工作流相同的方式把流分成更小的挑战是有用的:

  • 收集drop位置参数— — 生成工作流传递值,但我们需要使用它作为我们脚本中的 PowerShell 变量
  • 从主脚本调用部署脚本,通过拖drop位置传递值— — 使用我们早前配置的PowerShell 远程处理框架,我们需要 WSP 部署脚本调用生成计算机从 SharePoint 机器上
  • 返回成功/失败— — 此值必须从部署脚本传递到主脚本,然后返回到生成工作流中。

PowerShell 挑战

解决方案

收集drop位置

因为此值是从生成工作流中以命令行参数

传递的,它来自 ‘args’ 集合,并传递给主

脚本。

假定它是第一个参数,我们可

以用$dropLoc = $args [0]来将它收集到

PowerShell 变量中。

调用远程脚本

在 PowerShell中,Invoke-Command cmdlet

(不要与 InvokeProcess 工作流活动混淆)调用命令cmdlet 用于将一个或多个远程是用于在一台或更多的远程机器上执行脚

本的。当调用此 cmdlet 时,将使用

PowerShell Remoting infrastructure。

Invoke-Command有一个–ArgumentList

参数,它可用于将值传递到远程命令。

— — 我们为drop位置的值使用此参数。

假设已使用New-PSSession来启动

PowerShell 远程处理会话以此更正机器,并

且存储在一个名为$值中,省略了的调用

看起来像:Invoke-Command

-Session$s {param($dropLocation)

C:\builds\scripts\DeployCoreSolutions.ps1 @ PSBoundParameters}-ArgumentList $dropLoc

返回成功/失败

从 PowerShell 脚本中返回成功/失败的常见

方式是使用退出代码。以下显示为成功:

退出 0

这里的一个挑战是,在主脚本中使用

Invoke-Command时,远程脚本中的退

出代码不会作为返回值而返回。而当读取

内置的PowerShell变量$LASTEXITCODE

时,单独的命令必须被执行到远程的计

算机上:

Remotelastexitcode=Invoke-Command

–session 会话
$s-ScriptBlock {$LASTEXITCODE}

一旦我们在主脚本的本地变量中有了此值

,它就可以作为主脚本的返回代码而返回

到生成工作流中:remotelastexitcode

然后此值将被存储在 InvokeProcess 工作流

活动的结果属性中。

摘要

我们讨论了一些在TFS 生成工作流和PowerShell之间的关键机制,其中SharePoint/TFS 持续集成初学者工具包使用PowerShell来实现自动部署WSP。下面的图表可能会帮助把它们拼凑在一起:

image

虽然没有必要去了解这些过程运作的每一个细节,但那些走在我们前面,通过使用我们的入门包(或那些只是在探索的)实现持续集成的团队将受益于此背景。

在我们的系列中,已完成了几个重要的事情: 我们已经完成初始化 TFS 安装、 创建生成定义、 执行程序集版本控制、配置PowerShell远程处理,实现自动化 WSP 部署。在这一系列的下一篇文章中,我们将看看如何将实行自动化测试作为生成的一部分,尤其侧重于 Visual Studio 2010 编码 UI 测试。

资源:

No Comments - Leave a comment

Leave a comment


Welcome , today is 星期四, 2017 年 03 月 30 日