Azure Pipelines:如何在 Powershell 任务中成功执行 BITS 传输?
Azure Pipelines: How to do successful BITS-Transfer in Powershell task?
找不到任何地方的答案。
我需要我的管道调用必须多次执行 BITS 传输的 powershell 脚本。起初,脚本总是会因以下错误而退出:
Start-BitsTransfer : The operation being requested was not performed because the user has not
logged on to the
network. The specified service does not exist. (Exception from HRESULT: 0x800704DD)
然后,在 Powershell 任务中,我没有调用文件,而是将其更改为执行以下内联脚本:
powershell -File $(Build.Repository.LocalPath)\installer\assembly.win10.x64.ps1 -Credential Get-Credential [Domain]\[Username]
现在脚本运行了,但我在 Azure Pipelines 的日志中看到了这个:
Microsoft Visual C++ 2015 Redistributable x64 : downloading...
Start-BitsTransfer : The operation being requested was not performed because the user has not
logged on to the
network. The specified service does not exist. (Exception from HRESULT: 0x800704DD)
At C:\agents\_work\s\installer\assembly.win10.x64.ps1:9 char:5
+ Start-BitsTransfer -Source $Url -Destination $Target
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Start-BitsTransfer], COMException
+ FullyQualifiedErrorId :
System.Runtime.InteropServices.COMException,Microsoft.BackgroundIntelligentTransfer.Management.NewBitsTransferCommand
Microsoft Visual C++ 2015 Redistributable x64 : download completed
管道通过了,但是当我检查实际的可再发行组件的 .exe 时,它的大小为 0 字节。所以,文件夹似乎已经制作好并压缩了,文件也放在了它们需要的地方,但下载实际上并没有起作用。 我也在本地机器上测试了 powershell 脚本,没有问题。我该如何解决这个问题?
这是相关代码。前三块是下载相关的方法,最后是方法调用:
function Get-FileSha256([string]$Src) {
return (Get-FileHash "$Src" -Algorithm SHA256).Hash
}
function Download-File([string]$Comment, [string]$Url, [string]$Target) {
Write-Host "$Comment : downloading..."
New-Item -ItemType File -Path "$Target" -Force | Out-Null
Import-Module BitsTransfer
Start-BitsTransfer -Source $Url -Destination $Target
Write-Host "$Comment : download completed"
}
function Download-FileIfNecessary([string]$Comment, [string]$Url,
[string]$Target, [string]$Sha256) {
If (!(Test-Path $Target)) {
Download-File "$Comment" "$Url" "$Target"
return
}
$TargetSha256 = Get-FileSha256 $Target
If ($TargetSha256 -eq $Sha256) {
Write-Host "$Comment : already downloaded"
}
Else {
Download-File "$Comment" "$Url" "$Target"
}
}
Download-FileIfNecessary "Microsoft Visual C++ 2015 Redistributable x64" `
"https://download.microsoft.com/download/6/A/A/6AA4EDFF-645B-48C5-81CC-ED5963AEAD48/vc_redist.x64.exe" `
"$target_downloaded_vc_redist_dir15.v14.0.24215\vc_redist.x64.exe" `
"da66717784c192f1004e856bbcf7b3e13b7bf3ea45932c48e4c9b9a50ca80965"
我将提供使用 BITS 的替代方法,因为 BITS 设计为在请求者是本地经过身份验证的用户时使用,not by remote sessions, service accounts, or other non-interactive contexts。我已经 re-written Download-File
使用 Invoke-WebRequest
而不是
Start-BitsTransfer
:
Function Download-File {
Param(
[string]$Comment,
[string]$Url,
[string]$Target
)
Write-Host "$Comment : downloading..."
# We need to check that the target folder exists later
$targetFolder = Split-Path -Parent $Target
# Prepare cmdlet arguments for splatting
$iwrArgs = @{
UseBasicParsing = $true
Uri = $Url
OutFile = $Target
}
$newDirArgs = @{
ItemType = 'Directory'
Path = $targetFolder
}
# Create the target parent dir, if it doesn't exist
if ( !( Test-Path -PathType Container $targetFolder ) ) {
Write-Host "Creating directory $targetFolder"
New-Item @newDirArgs | Out-Null
}
# Workaround progress bar performance bug with Invoke-WebRequest
# (also affects Invoke-RestMethod) by disabling it
$OldProgressPreference = $ProgressPreference
$ProgressPreference = 'SilentlyContinue'
# Use a try / finally block to guarantee the
# original progress preference is changed back
try {
Invoke-WebRequest @iwrArgs -EA Stop
}
finally {
$ProgressPreference = $OldProgressPreference
}
}
如果您对每个部分的作用感兴趣,我已经对代码进行了评论。如果有问题我可以澄清。
您应该可以删除它来代替您当前的 Download-File
定义。我会推荐这个而不是尝试 hacky OS 技巧来使 BITS 在它不是设计的上下文中工作。也不建议将 BITS 与关键自动化一起使用,因为它的下载可以随时被 OS 暂停(例如,在下载更新时)。
请注意,我所说的 non-interactive 登录是正确的。从计划任务或 user-run 脚本中使用 BITS 应该是安全的,而不是从 Windows 服务(Azure 代理是)中使用。
找不到任何地方的答案。
我需要我的管道调用必须多次执行 BITS 传输的 powershell 脚本。起初,脚本总是会因以下错误而退出:
Start-BitsTransfer : The operation being requested was not performed because the user has not
logged on to the
network. The specified service does not exist. (Exception from HRESULT: 0x800704DD)
然后,在 Powershell 任务中,我没有调用文件,而是将其更改为执行以下内联脚本:
powershell -File $(Build.Repository.LocalPath)\installer\assembly.win10.x64.ps1 -Credential Get-Credential [Domain]\[Username]
现在脚本运行了,但我在 Azure Pipelines 的日志中看到了这个:
Microsoft Visual C++ 2015 Redistributable x64 : downloading...
Start-BitsTransfer : The operation being requested was not performed because the user has not
logged on to the
network. The specified service does not exist. (Exception from HRESULT: 0x800704DD)
At C:\agents\_work\s\installer\assembly.win10.x64.ps1:9 char:5
+ Start-BitsTransfer -Source $Url -Destination $Target
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Start-BitsTransfer], COMException
+ FullyQualifiedErrorId :
System.Runtime.InteropServices.COMException,Microsoft.BackgroundIntelligentTransfer.Management.NewBitsTransferCommand
Microsoft Visual C++ 2015 Redistributable x64 : download completed
管道通过了,但是当我检查实际的可再发行组件的 .exe 时,它的大小为 0 字节。所以,文件夹似乎已经制作好并压缩了,文件也放在了它们需要的地方,但下载实际上并没有起作用。 我也在本地机器上测试了 powershell 脚本,没有问题。我该如何解决这个问题?
这是相关代码。前三块是下载相关的方法,最后是方法调用:
function Get-FileSha256([string]$Src) {
return (Get-FileHash "$Src" -Algorithm SHA256).Hash
}
function Download-File([string]$Comment, [string]$Url, [string]$Target) {
Write-Host "$Comment : downloading..."
New-Item -ItemType File -Path "$Target" -Force | Out-Null
Import-Module BitsTransfer
Start-BitsTransfer -Source $Url -Destination $Target
Write-Host "$Comment : download completed"
}
function Download-FileIfNecessary([string]$Comment, [string]$Url,
[string]$Target, [string]$Sha256) {
If (!(Test-Path $Target)) {
Download-File "$Comment" "$Url" "$Target"
return
}
$TargetSha256 = Get-FileSha256 $Target
If ($TargetSha256 -eq $Sha256) {
Write-Host "$Comment : already downloaded"
}
Else {
Download-File "$Comment" "$Url" "$Target"
}
}
Download-FileIfNecessary "Microsoft Visual C++ 2015 Redistributable x64" `
"https://download.microsoft.com/download/6/A/A/6AA4EDFF-645B-48C5-81CC-ED5963AEAD48/vc_redist.x64.exe" `
"$target_downloaded_vc_redist_dir15.v14.0.24215\vc_redist.x64.exe" `
"da66717784c192f1004e856bbcf7b3e13b7bf3ea45932c48e4c9b9a50ca80965"
我将提供使用 BITS 的替代方法,因为 BITS 设计为在请求者是本地经过身份验证的用户时使用,not by remote sessions, service accounts, or other non-interactive contexts。我已经 re-written Download-File
使用 Invoke-WebRequest
而不是 Start-BitsTransfer
:
Function Download-File {
Param(
[string]$Comment,
[string]$Url,
[string]$Target
)
Write-Host "$Comment : downloading..."
# We need to check that the target folder exists later
$targetFolder = Split-Path -Parent $Target
# Prepare cmdlet arguments for splatting
$iwrArgs = @{
UseBasicParsing = $true
Uri = $Url
OutFile = $Target
}
$newDirArgs = @{
ItemType = 'Directory'
Path = $targetFolder
}
# Create the target parent dir, if it doesn't exist
if ( !( Test-Path -PathType Container $targetFolder ) ) {
Write-Host "Creating directory $targetFolder"
New-Item @newDirArgs | Out-Null
}
# Workaround progress bar performance bug with Invoke-WebRequest
# (also affects Invoke-RestMethod) by disabling it
$OldProgressPreference = $ProgressPreference
$ProgressPreference = 'SilentlyContinue'
# Use a try / finally block to guarantee the
# original progress preference is changed back
try {
Invoke-WebRequest @iwrArgs -EA Stop
}
finally {
$ProgressPreference = $OldProgressPreference
}
}
如果您对每个部分的作用感兴趣,我已经对代码进行了评论。如果有问题我可以澄清。
您应该可以删除它来代替您当前的 Download-File
定义。我会推荐这个而不是尝试 hacky OS 技巧来使 BITS 在它不是设计的上下文中工作。也不建议将 BITS 与关键自动化一起使用,因为它的下载可以随时被 OS 暂停(例如,在下载更新时)。
请注意,我所说的 non-interactive 登录是正确的。从计划任务或 user-run 脚本中使用 BITS 应该是安全的,而不是从 Windows 服务(Azure 代理是)中使用。