You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Get-AzAccessToken令牌格式及在Bicep部署脚本中使用问题

Azure SQL Server命令在Bicep DeploymentScript中失效(6月5日微软破坏性变更后)

我有一个在Azure DevOps中作为Bicep DeploymentScript执行的脚本,原本用于执行Azure SQL Server命令,自今年6月5日微软的破坏性变更后失效。目前已采用对应MS Graph新语法,但仍存在以下问题:

  • (Get-AzAccessToken -ResourceTypeName MSGraph).Token的格式是什么?
  • 如何在Invoke-Sqlcmd中使用该令牌,并从Bicep DeploymentScript返回?
  • 如何获取令牌字符串并从DeploymentScript返回?

注:已尝试使用$token和$secureToken,均未生效。

现有部署脚本代码

resource identity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = {
  name: sqlAdminUmiName
}

var sqlServerHostname = environment().suffixes.sqlServerHostname
var tokenResourceUrl = 'https://${substring(sqlServerHostname, 1)}'
      
resource deploymentScriptServerGroupAssignment 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
  name: name
  location: location
  kind: 'AzurePowerShell'
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${identity.id}': {}
    }
  }
  properties: {
    azPowerShellVersion: '8.3'
    arguments: '-dbHost "${dbHost}" -tokenResourceUrl "${tokenResourceUrl}" -dbName "${dbName}" -fxaName "${fxaName}" '
    scriptContent: '''
      param(
        [string] $dbHost,
        [string] $tokenResourceUrl,
        [string] $dbName,
        [string] $fxaName,
        [string] $dbRoleNames
      )
      
      echo "Step 0: about to Install-Module Microsoft.Graph -Force"
      Install-Module -Name SqlServer -Force
      Import-Module -Name SqlServer
      $token = (Get-AzAccessToken -ResourceTypeName MSGraph).Token
      echo "Step 1: token - $token"

      $secureToken = ConvertTo-SecureString $token -AsPlainText -Force
      echo "Step 2: secureToken - $secureToken"
      
      
      $query = @()
      $query += "DROP USER IF EXISTS `"$fxaName`""
      $query += "CREATE USER `"$fxaName`" FROM external provider"
      $query += "ALTER ROLE db_owner ADD MEMBER `"$fxaName`""
      $query += "ALTER ROLE db_datareader ADD MEMBER `"$fxaName`""
      $query += "ALTER ROLE db_datawriter ADD MEMBER `"$fxaName`""
      $query += "ALTER ROLE db_ddladmin ADD MEMBER `"$fxaName`""

      $query = $query -join ";"
      Invoke-Sqlcmd -ServerInstance $dbHost -Database $dbName -AccessToken "$secureToken" -Query $query
    '''
    retentionInterval: 'PT1H'
    cleanupPreference: 'OnSuccess'
    forceUpdateTag: currentTime
  }
}

部署错误信息

Microsoft.Data.SqlClient.SqlException (0x80131904): Login failed for user '<token-identified principal>'.

Microsoft.SqlTools.ServiceLayer.BatchParser.BatchParserException: Incorrect syntax was encountered while parsing

同类脚本返回错误(精简片段)

$token = (Get-AzAccessToken -ResourceTypeName MSGraph).Token
echo &quot;Step 1: token - $token&quot;

$secureToken = ConvertTo-SecureString $token -AsPlainText -Force
echo &quot;Step 2: secureToken - $secureToken&quot;

Write-Host &quot;##vso[task.setvariable variable=dbToken;isOutput=true]$secureToken&quot;

$DeploymentScriptOutputs = @{}
$DeploymentScriptOutputs['dbAccess'] = $secureToken

错误信息:

The template output 'dbToken' is not valid: The provided value for the template output 'dbToken' is not valid. Expected a value of type 'String, Uri', but received a value of type 'Object'.


问题1:(Get-AzAccessToken -ResourceTypeName MSGraph).Token的格式

该命令返回的是Base64编码的JWT令牌字符串,由Header、Payload、Signature三部分组成,用.分隔。你可以通过echo $token直接查看完整字符串,但注意不要在生产环境输出敏感令牌内容。

问题2:在Invoke-Sqlcmd中正确使用令牌并返回

你的核心问题有两个:

  1. 令牌资源目标错误:连接Azure SQL需要的是SQL数据库服务的资源令牌,而非MS Graph的令牌。应使用Get-AzAccessToken -ResourceUrl $tokenResourceUrl(或直接指定https://database.windows.net/),而非ResourceTypeName MSGraph。
  2. Invoke-Sqlcmd参数类型错误:-AccessToken参数接受明文字符串,不需要将令牌转换为SecureString。

修改后的脚本核心逻辑:

# 替换令牌获取逻辑,目标为SQL资源
$token = (Get-AzAccessToken -ResourceUrl $tokenResourceUrl).Token
echo "Step 1: token - $token"

# 直接使用明文令牌调用Invoke-Sqlcmd
Invoke-Sqlcmd -ServerInstance $dbHost -Database $dbName -AccessToken $token -Query $query

另外,SQL语句拼接时需注意语法规范,建议用Here-String避免引号转义问题:

$query = @"
DROP USER IF EXISTS "$fxaName";
CREATE USER "$fxaName" FROM external provider;
ALTER ROLE db_owner ADD MEMBER "$fxaName";
ALTER ROLE db_datareader ADD MEMBER "$fxaName";
ALTER ROLE db_datawriter ADD MEMBER "$fxaName";
ALTER ROLE db_ddladmin ADD MEMBER "$fxaName";
"@

问题3:获取令牌字符串并从DeploymentScript返回

$secureToken是SecureString类型,而DeploymentScript的输出仅支持字符串/URI类型,因此直接返回明文令牌$token即可:

# 正确返回令牌字符串到DeploymentScript输出
$DeploymentScriptOutputs = @{}
$DeploymentScriptOutputs['dbAccess'] = $token

# Azure DevOps任务输出同样使用明文令牌
Write-Host "##vso[task.setvariable variable=dbToken;isOutput=true]$token"

内容的提问来源于stack exchange,提问作者Aiden Dipple

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 22:33:16