Invoke-RestMethod:远程服务器返回错误:(401)未经授权

时间:2019-08-14 11:32:06

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

我想从Azure devops Security刀片服务器获取组列表。我准备了代码。我是Azure Devops中的“贡献者”组的成员,正在使用cmd-let Invoke-RestMethod。我正在测试从笔记本电脑连接到我的Azure帐户的这段代码,而不是在Azure自动化或Azure管道上对此进行测试。我仍然遇到问题->以下错误消息: Invoke-RestMethod:远程服务器返回错误:(401)未经授权。

##My Function
function GetUrl() {
    param(
        [string]$orgUrl, 
        [hashtable]$header, 
        [string]$AreaId
    )

$orgResourceAreasUrl = [string]::Format("{0}/_apis/resourceAreas/{1}?api-preview=5.0-preview.1", $orgUrl, $AreaId)

    # Do a GET on this URL (this returns an object with a "locationUrl" field)
    $results = Invoke-RestMethod -Uri $orgResourceAreasUrl -Headers $header

    # The "locationUrl" field reflects the correct base URL for RM REST API calls
    if ("null" -eq $results) {
        $areaUrl = $orgUrl
    }
    else {
        $areaUrl = $results.locationUrl
    }

    return $areaUrl
}

  $token =[System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalToken)"))
$header = @{authorization = "Basic $token"}

  $orgUrlAD = "https://vsaex.dev.azure.com/OrganizationName"
$personalToken = "MyPersonalToken"

  ##Function execution
  Write-Host "AD tests"
  $coreAreaId = "xxx"
  $tfsBaseUrl = GetUrl -orgUrl $orgUrlAD -header $header -AreaId 
$coreAreaId

  $projectsUrl = "$($tfsBaseUrl)_apis/groupentitlements?api-version=5.0-preview.1"

  $projects = Invoke-RestMethod -Uri $projectsUrl -Method Get -ContentType "application/json" -Headers $header

  $projects.value | ForEach-Object {
    Write-Host $_.name
}

Invoke-RestMethod:远程服务器返回错误:(401) 未经授权。

1 个答案:

答案 0 :(得分:1)

  

(401)未经授权。

这意味着无法正确获取和使用您的令牌。

由脚本顺序引起的错误,作为常规逻辑,它按行顺序编译。而且,在您的脚本中,您的$personalToken位于$token之后。这将导致在跟随脚本中,$personalToken中没有值,因此$token无效。

  $token =[System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalToken)"))

要解决此问题,只需在$personalToken$personalToken之间更改顺序:

$personalToken = "{Your PersonalToken}"
$token =[System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalToken)"))
$header = @{authorization = "Basic $token"}

更新: 这是已在我的组织中成功完成的脚本,您可以尝试使用。只需将您的组织名称替换为$orgUrlAD的值就可以了。

function GetUrl() {
$orgUrl = $env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI
$AreaId="efc2f575-36ef-48e9-b672-0c6fb4a48ac5"
$orgResourceAreasUrl = [string]::Format("{0}/_apis/resourceAreas/{1}?api-preview=5.0-preview.1", $orgUrl, $AreaId)

# Do a GET on this URL (this returns an object with a "locationUrl" field)
$results = Invoke-RestMethod -Uri $orgResourceAreasUrl -Headers $header

# The "locationUrl" field reflects the correct base URL for RM REST API calls
    if ("null" -eq $results) {
        $areaUrl = $orgUrl
    }
    else {
        $areaUrl = $results.locationUrl
    }

    return $areaUrl
}
$personalToken = "yvufhmgdgwsy-xxxxxxxx-a2gagb4yfvcct5kdq6q"
$token =[System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalToken)"))
$header = @{authorization = "Basic $token"}

$orgUrlAD = "https://vsaex.dev.azure.com/{org name}"

##Function execution
Write-Host "AD tests"
$coreAreaId = "xxx"
$tfsBaseUrl = GetUrl -orgUrl $orgUrlAD -header $header -AreaId 
$coreAreaId

$projectsUrl = $orgUrlAD+"/_apis/groupentitlements?api-version=5.0-preview.1"
Write-Host $projectsUrl
$projects = Invoke-RestMethod -Uri $projectsUrl -Method Get -ContentType "application/json" -Headers $header
Write-Host "Pipeline = $($projects | ConvertTo-Json -Depth 100)"
$projects.value | ForEach-Object {
Write-Host $_.name
}