【问题标题】:Powershell Foreach loop to iterate through API output and display variable values line by linePowershell Foreach 循环遍历 API 输出并逐行显示变量值
【发布时间】:2021-06-28 22:07:41
【问题描述】:

我正在 Postman 中运行一些 Azure DevOps API 查询,这些查询成功返回了预期的结果,其中的一个 sn-p 在下面共享,仅代表几十个类似迭代输出中的一个。为了便于说明,我们假设Id值为66的下面的sn-p只是100s之一。

        "id": 66,
        "buildNumber": "20210401.7",
        "status": "completed",
        "result": "succeeded",
        "queueTime": "2021-04-01T16:50:04.9218848Z",
        "startTime": "2021-04-01T16:50:15.3583291Z",
        "finishTime": "2021-04-01T16:50:53.7221605Z",

我现在希望使用 Powershell foreach 循环迭代解析 100 多条记录,将“id”、“buildNumber”、“status”和“result”值逐行输出到输出文件中。

所需的输出应如下所示:

        "id": 66,
        "buildNumber": "20210401.7",
        "status": "completed",
        "result": "succeeded",

        "id": 65,
        "buildNumber": "20210331.5",
        "status": "completed",
        "result": "failed",

        "id": 64,
        "buildNumber": "20210331.4",
        "status": "completed",
        "result": "succeeded",

任何关于如何实现这一目标的建议或想法将不胜感激。

[[我当前的 POWERSHELL 脚本已删除个人变量]]

清除主机 $connectionToken="[MY-PAT]" $base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))

$url = 'https://dev.azure.com/[MY-AZURE-ORG]/[MY-TEAM-PROJECT]/_apis/build/builds?api-version=6.0'

$PackageInfo = (Invoke-RestMethod -Uri $url -Method Get -UseDefaultCredential -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)})

$LatestVersion= $PackageInfo.value.buildnumber |选择对象-first 1

$BuildResult= $PackageInfo.value.result |选择对象-first 1

foreach ($PackageInfo 中的$item) { 写主机 " " 写入主机“最新版本 = $LatestVersion”“|” “构建结果 = $BuildResult” 写主机 " "
}

[[以上脚本的输出]]

从上图中可以看出,通过检索最后的构建记录,我得到了我的 Powershell 脚本返回的上述输出,这很棒。

然而,我不仅仅关注最后一个构建记录。我希望逐行列出所有构建记录。因此,理想情况下,对我现有脚本的任何改进都将是最合适的,因为我认为它只需要稍作调整。

省略 Select-Object 会返回所有预期的数据,但采用以下格式,不会以我喜欢的单行格式显示。

【问题讨论】:

  • 试试foreach ($build in $PackageInfo.value) { 'Build: {0} | Result: {1}' -f $_.buildnumber, $_.result }
  • @Theo,我给了你的建议,用你的替换了我的 foreach 循环,但我担心你的建议不会返回任何构建数据值。我得到的是 Build: 和 Result: 每条记录的标签逐行显示,这很好,但不是完整的解决方案。现在只需要获取输出中显示的相应数据值..
  • @Theo,如果您能够在我的原始脚本(上图)的相关部分进行说明,我将不胜感激,我可以在其中插入您提出的更改以确保我获得内部版本号和构建结果按预期显示。
  • 对不起,我之前的评论有一个错误.. 而不是你的 foreach 循环尝试 foreach ($build in $PackageInfo.value) { 'Build: {0} | Result: {1}' -f $build.buildnumber, $build.result } 或做 $PackageInfo.value | ForEach-Object { 'Build: {0} | Result: {1}' -f $_.buildnumber, $_.result }

标签: powershell rest for-loop foreach while-loop


【解决方案1】:

您正在获取构建信息,因此我假设您使用的是 Azure DevOps API:

https://dev.azure.com/{organization}/{project}/_apis/build/builds?api-version=6.0

使用 PowerShell,首先您需要进行身份验证, 您可以使用 OAuth2 身份验证: 参考:https://docs.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/oauth?view=azure-devops

可以使用PAT访问方式,但是需要从UI手动生成token。

function getBearer([string]$TenantID, [string]$ClientID, [string]$ClientSecret)
{
  $TokenEndpoint = {https://login.windows.net/{0}/oauth2/token} -f $TenantID 
  $ARMResource = "https://management.core.windows.net/";

  $Body = @{
          'resource'= $ARMResource
          'client_id' = $ClientID
          'grant_type' = 'client_credentials'
          'client_secret' = $ClientSecret
  }

  $params = @{
      ContentType = 'application/x-www-form-urlencoded'
      Headers = @{'accept'='application/json'}
      Body = $Body
      Method = 'Post'
      URI = $TokenEndpoint
  }

  $token = Invoke-RestMethod @params

  Return "Bearer " + ($token.access_token).ToString()
}


    $header = @{
Authorization = getBearer $TenantId $ClientId $ClientSecret
content-type = 'application/json'
}

$ApiUri = "https://dev.azure.com/{organization}/{project}/_apis/build/builds?api-version=6.0"

$data = (Invoke-RestMethod  -Uri $ApiUri -Method Get -Headers $header).value

$OutputFile = "<file-name>"

Class BuildObject {
    id [String]
    buildNumber [String]
    status [String]
    result [String]
}
$BuildObj = New-Object $BuildObject


foreach($buildItem in $data) {
    $BuildObj.id = $buildItem.id
    $BuildObj.buildNumber = $buildItem.buildNumber
    $BuildObj.status = $buildItem.status
    $BuildObj.result = $buildItem.result
    
    $BuildObj | OutFile -FilePath $OutputFile -Append
}
    

【讨论】:

  • 我尝试运行您的脚本,但不幸遇到了一些错误,我将在下面分享截图。
  • 我尝试运行您的脚本,但不幸遇到了一些错误,我将在下面分享截图。说了这么多,鉴于遇到的错误,我个人认为您的脚本可能有点矫枉过正,因为我有一个更加简化的脚本,我希望对其稍作修改以达到预期的结果。再次,我将通过将它附加到我原来的问题来分享这个(我的道歉,我也许应该早点这样做),因为我相信它会增加更多的上下文,然后可以在未来对其他人有用。欢迎您就如何完善该脚本提供反馈。
  • [[SCRIPT ERROR SCREENDUMP]] 在第 29 行 char:8 + content-type = 'application/json' + ~ 输入哈希文字后缺少 '=' 运算符。在 line:38 char:6 + Class BuildObject { + ~ 在散列文字的键之后缺少“=”运算符。在 line:38 char:6 + Class BuildObject { + ~ 哈希文字不完整。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : MissingEqualsInHashLiteral
猜你喜欢
  • 2015-10-21
  • 1970-01-01
  • 2017-05-21
  • 1970-01-01
  • 2018-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多