【问题标题】:How to download pipeline artifacts from azure pipeline to local using powershell?如何使用 powershell 将管道工件从 azure 管道下载到本地?
【发布时间】:2020-09-03 07:51:47
【问题描述】:

我需要从本地计算机上的 azure 管道下载工件。任何人都可以使用 powershell 脚本帮助执行此操作吗?

【问题讨论】:

  • 无法获得您的最新信息,我的解决方法对您有帮助吗?或者,如果您有任何疑问,请随时在此处分享。
  • 我使用了您建议的方法将我的 PAT 令牌转换为 Base64,然后我用它来创建在 Invoke-Restmethod 中使用的授权标头。感谢您帮助我找到解决方案。

标签: azure-devops azure-pipelines azure-devops-rest-api


【解决方案1】:
$token = "xxx"
    
$url="https://dev.azure.com/{OrgName}/{ProjectName}/_apis/build/builds/{BuildID}/artifacts?artifactName={ArtifactName}&api-version=6.1-preview.5&%24format=zip"
    
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))
    
$response = Invoke-RestMethod -Uri $url -Headers @{Authorization = "Basic $token"} -Method Get -ContentType application/zip -OutFile "{SomePath}\Response.zip"

注意:在url后面加上&%24format=zip并设置-ContentType application/zip -OutFile "{SomePath}\Response.zip"

您需要将token(PAT),OrgName,ProjectName,BuildID,ArtifactName 替换为您自己的值。并选择一个现有的路径来保存响应,例如C:\pub\Response.zip。我有现有的路径C:\pub,运行 PS 脚本后,我可以创建一个包含我需要的工件的 Response.zip

另外,你也可以尝试通过c#代码下载构建神器。详情请参考此ticket

static readonly string TFUrl = "https://dev.azure.com/OrgName/";
static readonly string UserPAT = "PAT";

static void Main(string[] args)
{
    try
    {
        int buildId = xx; // update to an existing build definition id
        string artifactName = "drop"; //default artifact name
    //  string project = "projectName";
        ConnectWithPAT(TFUrl, UserPAT);

        Stream zipStream = BuildClient.GetArtifactContentZipAsync(buildId, artifactName).Result; //get content
        using (FileStream zipFile = new FileStream(@"C:\MySite\test.zip", FileMode.Create))
            zipStream.CopyTo(zipFile);
        Console.WriteLine("Done");
    }
    catch (Exception ex)
    {
        Console.WriteLine("Exception: " + ex.Message);
        if (ex.InnerException != null) Console.WriteLine("Detailed Info: " + ex.InnerException.Message);
        Console.WriteLine("Stack:\n" + ex.StackTrace);
    }
}

【讨论】:

  • 一气呵成,您的代码适用于 PowerShell...谢谢。
  • 为什么你的网址中有%24?不应该是&api-version=6.1-preview.5&format=zip吗?
【解决方案2】:

上面提供的解决方案不起作用或不再起作用 - API 似乎已更改。如果您使用这些解决方案,您会收到要求您登录的 HTML 内容。

新 API 返回带有 downloadUrl 的 JSON:

{
  "id": 105284,
  "name": "Artifact",
  "resource": {
    ...
    "downloadUrl": "https://artprodsu6weu.artifacts.visualstudio.com/....."        
  }
}

所以这里有一些可以正常工作的代码:

$BuildId = "154782"
$ArtifactName = "Artifact"
$OutFile = "Artifact.zip"
$OrgName="myorg"
$ProjectName="myproject"

$PAT = "**************"
    
$url = "https://dev.azure.com/$($OrgName)/$($ProjectName)/_apis/build/builds/$($BuildID)/artifacts?artifactName=$($ArtifactName)&api-version=&format=zip"
    
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($PAT)"))
    
# Get the download URL
$response = Invoke-RestMethod -Uri $url -Headers @{Authorization = "Basic $token"}
$downloadUrl = $response.resource.downloadUrl

# Download the artifact
$response = Invoke-WebRequest -Uri $downloadUrl -Headers @{Authorization = "Basic $token"} -OutFile $OutFile

【讨论】:

  • 非常有帮助!顺便说一句,前两个变量声明后的逗号应该被删除。我试图在这里编辑它们,但 SO 说编辑必须至少有 6 个字符。
【解决方案3】:

您可以使用Artifacts Rest API:

$token = "Your PAT"

# Create Authorization header
$headers = @{"Authorization" = "Bearer $token"}

# Create Web client - used to downlaod files
$wc = New-Object System.Net.WebClient
$wc.Headers.Add("Authorization", $headers["Authorization"])

            # Get Build artifact details
            $buildId = "the artifats build id"
            $artifactsUrl = "https://dev.azure.com/{organization}/{project}/_apis/build/builds/$buildId/artifacts?api-version=4.1"
            $buildArtifacts = Invoke-RestMethod -Method Get -Headers $headers -Uri $artifactsUrl

            foreach($buildArtifact in $buildArtifacts.value){
                # Download build artifacts - ZIP files
                $url = $buildArtifact.resource.downloadUrl
                $output = Join-Path $artifactsDir "$($buildArtifact.name).zip"
                $wc.DownloadFile($url, $output)
            }

$wc.Dispose()

【讨论】:

  • 您可以尝试使用Write-Host 调试这些行并检查哪一行不起作用?
  • 您是否将{organization}{project} 中的值替换为您的项目详细信息并将值放入$buildId
  • 我正在运行所有必需的更改
猜你喜欢
  • 1970-01-01
  • 2022-08-20
  • 1970-01-01
  • 2020-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-09
  • 1970-01-01
相关资源
最近更新 更多