【问题标题】:Invoke-RestMethod : The remote server returned an error: (401) UnauthorizedInvoke-RestMethod : 远程服务器返回错误: (401) Unauthorized
【发布时间】:2026-01-27 05:40:01
【问题描述】:

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

【问题讨论】:

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


    【解决方案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
    }
    

    【讨论】:

    • 嗨,感谢这个解决方案,我根据您的建议更正了我的代码,但存在同样的问题,现在的顺序是:函数体、$personalToken、$token、$header、函数执行。
    • 我在我这边测试过,这是我的结果:imgur.com/a/ZGLYfkr。对我来说是成功的。我还在第二张照片中上传了我的脚本。您可以查看我们的区别。
    • 我看到了你的代码,在我的环境中不起作用,我将我的代码与你的建议一起使用,并在输出中得到不完整的结果,并遵循信息 "span class="error">Microsoft Internet Explorer' ;s 增强的安全配置当前已在您的环境中启用。这种增强的安全级别会阻止我们的 Web 集成体验正确显示或执行。要继续您的操作,请禁用此配置或联系您的管理员。"
    • @tester81 如果我没有误解,我认为这条消息仍然与 PAT 相关。您介意生成一个新令牌并重试吗?参考this similar issue
    • @tester81 你好,现在怎么样了?当您尝试使用生成的新令牌时,错误是否消失了?