tester81
tester81

Reputation: 595

Invoke-RestMethod : The remote server returned an error: (401) Unauthorized

I would like to get list of groups from Azure devops Security blade. I prepared a code. I am a member of Contributors group in Azure Devops, I am using cmd-let Invoke-RestMethod. I am testing this piece of code connected to my Azure account from laptop, not tested this on Azure Automation or Azure pipelines. I am still facing an issue --> Error message below: Invoke-RestMethod : The remote server returned an error: (401) Unauthorized.

##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 : The remote server returned an error: (401) Unauthorized.

Upvotes: 0

Views: 24826

Answers (1)

Mengdi Liang
Mengdi Liang

Reputation: 19026

(401) Unauthorized.

This means that your token is not be get and used correctly.

The error caused by the order of the script, as the normal logic, it compiled by line order. And also, in your script, your $personalToken is behind of $token. This will result that in the follow script, there is no value in $personalToken, so that $token is unvalid.

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

To solve this, just change the order between $personalToken and $personalToken:

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

Update: This is the completed script which is successfully on my org, you can try with that. Just replace with your org name in the value of $orgUrlAD is ok.

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
}

Upvotes: 1

Related Questions