Azure DevOps管道用PowerShell从Azure Repos下载文件报错解决
问题答复
你的两个疑问的明确结论
$filePath参数的作用:你当前写的$(Build.ArtifactStagingDirectory)是管道预定义的文件夹路径(工件暂存目录),但Out-File需要传入包含文件名、后缀的完整文件保存路径,直接传文件夹路径会触发写入错误。- 请求URL格式:你当前构造的URL是错误的。该路径是仓库Web页面的访问路径,不是REST API的调用路径,且缺少项目名、文件所在分支两个必填参数,会直接返回404或鉴权失败。
现有脚本的其他错误
- YAML格式错误:
PowerShell@2任务的inputs节点下的参数没有正确缩进,会导致管道无法正常加载任务 - 凭据风险:手动硬编码PAT存在泄露风险,且PAT有过期时间,维护成本高
- 下载逻辑错误:下载zip这类二进制文件时,用管道传给
Out-File会默认以文本编码写入,导致文件损坏;application/text的Content-Type配置也不符合二进制文件下载要求 - 权限配置缺失:如果要使用管道内置访问令牌,没有在任务环境变量中显式声明传入
修正后的可直接运行的脚本方案
该方案不需要手动生成PAT,直接使用管道运行时自动生成的内置访问令牌,凭据自动轮换无泄露风险:
- task: PowerShell@2 displayName: Get .zip from Azure Repos inputs: targetType: 'inline' script: | # 配置参数:替换成你实际的项目、分支、文件名信息 $orgName = "devopstry2305" $projectName = "替换为你的Azure DevOps项目名称" $repoName = "2305first_try" $branchName = "main" # 替换为zip文件所在的分支名 $repoFilePath = "/TempTest.zip" $saveFileName = "TempTest.zip" # 拼接完整保存路径 $fullSavePath = Join-Path '$(Build.ArtifactStagingDirectory)' $saveFileName # 构造鉴权信息 $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "", "$(System.AccessToken)"))) # 构造正确的REST API请求地址 $apiUrl = "https://dev.azure.com/$orgName/$projectName/_apis/git/repositories/$repoName/items?path=$repoFilePath&download=true&versionDescriptor.version=$branchName&api-version=7.1" # 下载二进制文件,直接用-OutFile参数避免转码损坏 Invoke-RestMethod -Uri $apiUrl -Method Get -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -OutFile $fullSavePath # 校验下载结果 if (Test-Path $fullSavePath) { Write-Host "文件下载成功,保存路径:$fullSavePath,文件大小:$((Get-Item $fullSavePath).Length) 字节" } else { Write-Error "文件下载失败,未找到目标文件" exit 1 } env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) # 必须配置,才能将内置令牌传入脚本
如果运行时报403权限错误,进入项目设置->Repos->仓库->选择目标仓库->权限页,搜索
[你的项目名] Build Service账号,为其授予读取权限即可。
更简单的无脚本方案
如果不想手写API调用逻辑,可以直接使用官方的文件下载任务,可视化配置即可完成需求:
- task: DownloadFilesFromGit@0 displayName: Download zip file inputs: GitRepositoryConnection: '默认的Azure Repos服务连接' # 同组织下的管道默认会带该连接,直接选择即可 GitRepository: '2305first_try' Branch: 'main' # 替换为实际分支名 Contents: 'TempTest.zip' # 要下载的文件在仓库中的路径 TargetFolder: '$(Build.ArtifactStagingDirectory)'
内容的提问来源于stack exchange,提问作者EaredGen
相关产品推荐
相关产品推荐

