如何从 vNext 构建代理上的自定义脚本加载 PowerShell 模块?

How to load PowerShell Module from custom script on vNext build agent?

我正在使用标准的 TFS vNext 构建步骤来执行 PowerShell 脚本。在脚本中,我试图利用标准 TFS 代理模块中的一些功能。

此处列出: http://blog.majcica.com/2015/11/14/available-modules-for-tfs-2015-build-tasks/

我在构建步骤中发现的许多 PowerShell 脚本中看到了以下两行:

Import-Module "Microsoft.TeamFoundation.DistributedTask.Task.Internal"
Import-Module "Microsoft.TeamFoundation.DistributedTask.Task.Common"

我试图在我的脚本中使用相同的行,但是我得到了错误:

VERBOSE: Loading module from path 
'C:\TFS2015-Agent\Agent1\agent\agent\worker\Modules\Microsoft.TeamFoundation.DistributedTask.Task.Common\Microsoft.TeamFoundation.DistributedTask.Task.Common.dll'.
Import-Module : Could not load file or assembly 'Microsoft.TeamFoundation.DistributedTask.Agent.Interfaces, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. 
The system cannot find the file specified.
At C:\tfsVnBw1\s\Configuration\BuildScripts\CommonFunctions.ps1:25 char:5
+ Import-Module "Microsoft.TeamFoundation.DistributedTask.Task.Common" - Error ... + CategoryInfo : NotSpecified: (:) [Import-Module], FileNotFoundException + FullyQualifiedErrorId : System.IO.FileNotFoundException,Microsoft.PowerShell.Commands.ImportModuleCommand

如果我尽量不导入,它会这样写:

The 'Find-Files' command was found in the module 'Microsoft.TeamFoundation.DistributedTask.Task.Common', 
but the module could not be loaded. For more information, run 'Import-Module Microsoft.TeamFoundation.DistributedTask.Task.Common'. 
At C:\tfsVnBw1\s\Configuration\BuildScripts\CommonFunctions.ps1:71 char:16
+ $files = @(FindFiles $filePattern)
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Find-Files:String) [FindFiles], CommandNotFoundException + FullyQualifiedErrorId : CouldNotAutoloadMatchingModule

是否无法使用来自 'normal' PowerShell 脚本的模块,而不仅仅是来自注册为实际构建步骤的 PowerShell 脚本?

尝试指定build agent的模块路径,如:

 # Import the Task.Common and Task.Internal dll that has all the cmdlets we need for Build
$agentWorkerModulesPathRoot = "$($env:AGENT_HOMEDIRECTORY)\agent\worker"
$agentDistributedTaskInterfacesModulePath = "$agentWorkerModulesPathRoot\Microsoft.TeamFoundation.DistributedTask.Agent.Interfaces.dll"
$agentWorkerModulesPath = "$($env:AGENT_HOMEDIRECTORY)\agent\worker\Modules"
$agentDistributedTaskCommonModulePath = "$agentWorkerModulesPath\Microsoft.TeamFoundation.DistributedTask.Task.Common\Microsoft.TeamFoundation.DistributedTask.Task.Common.dll"

Write-Host "Importing VSTS Module $agentDistributedTaskInterfacesModulePath"
Import-Module $agentDistributedTaskInterfacesModulePath
Write-Host "Importing VSTS Module $agentDistributedTaskCommonModulePath"
Import-Module $agentDistributedTaskCommonModulePath

Is it not possible to use the Modules from 'normal' PowerShell scripts and not only from PowerShell scripts registered as an actual build step?

可以在构建步骤中使用 powershell 脚本引用模块。我更喜欢使用 inline powershell task,因为这意味着我不必为了更改代码的打包方式而经历繁琐的门控签入。我经常使用它来做诸如...

  • 从 TFVC 中的共享项目下载通用程序集版本控制 ps1 脚本并执行它以使用内部版本号标记程序集、nuget 包等。
  • Save-Module 用于私有 PS 存储库中的模块,并将其包含在工件中(安装助手)
  • Save-Module 再次复制到临时文件夹,然后导入模块并使用它对正在构建的代码执行某些操作。
  • 生成发行说明或类似文档

...但您也可以使用常规 "Run a powershell script" 来完成所有这些操作。

也许更简单的方法是将模块放在路径中,如果它 < 5.1,则更新 powershell,如果构建服务器上有 powershell 3 或更高版本,并且该模块已经安装在服务器和代理帐户中$PSModulePath,那么你甚至不需要Import -Module,你可以直接调用该模块中的命令。