如何在 Packer 配置器中使用 BITS 下载文件?

How to download a file using BITS in a Packer provisioner?

我正在 PowerShell 中为 CI 管道上的 Packer 构建的 Windows 映像编写配置脚本。此过程涉及下载几个大文件。我的印象是 BITS is faster than Invoke-WebRequest,所以我决定使用 BITS 异步下载这些大文件。

问题是 BITS will only process jobs for users that are interactively logged on...

BITS transfers files only when the job's owner is logged on to the computer (the user must have logged on interactively). BITS does not support the RunAs command.

...unless the job was submitted by a service account.

You can use BITS to transfer files from a service. The service must use the LocalSystem, LocalService, or NetworkService system account. These accounts are always logged on; therefore, jobs submitted by a service using these accounts always run.

但即便如此,还是有问题:

If a service running under a system account impersonates the user before calling BITS, BITS responds as it would for any user account (for example, the user needs to be logged on to the computer for the transfer to occur).

这是一个问题,因为供应脚本以管理员帐户运行,而不是服务帐户,因此必须以交互方式登录才能使用 BITS。 这恰好是Packer的行为,所以我无法改变这个。 我错了,我可以改变这个。请参阅我的最终答案。 如何在一个 PowerShell 脚本中执行以下操作?

您可以使用 psexec 运行 管理员内容的具有 SYSTEM 权限的辅助脚本,并让主脚本识别 psexec 进程的退出代码以确认它已成功执行。

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/start-process?view=powershell-7.1

https://docs.microsoft.com/en-us/sysinternals/downloads/psexec#:~:text=PsExec%20is%20a%20light-weight,to%20manually%20install%20client%20software.

https://weblogs.asp.net/soever/returning-an-exit-code-from-a-powershell-script

事实证明有一个解决方案,尽管它是特定于 Packer 的。我没有过多提及我对它的使用,因为我认为它没有那么重要。

与我最初的看法相反,Packer 的 PowerShell 配置器 lets you run the provisioning script with elevated privileges as any user...

  • elevated_user and elevated_password (string) - If specified, the PowerShell script will be run with elevated privileges using the given Windows user.
provisioner "powershell" {
   elevated_user = "Administrator"
   elevated_password = build.Password
}

...包括服务用户。

If you specify an empty elevated_password value then the PowerShell script is run as a service account. For example:

provisioner "powershell" {
  elevated_user = "SYSTEM"
  elevated_password = ""
}

相应地调整我的 Packer 模板的 provisioner 块后,我现在可以确认 Start-BitsTransfer 和朋友按预期工作。无需传递复杂的参数或玩弄会话。